---
--类名: DoEventHandler.lua
--创建日期: 2015-9-8
--创建人: 陈小虎
--功能描述: 事件处理
--修改内容:
--修改日期:
--修改人:
--修改备注:
--

local Vector = require("app.utils.Vector")

--事件
local ChangeMapEvent = require("app.scripts.events.ChangeMapEvent")
local WalkEvent = require("app.scripts.events.WalkEvent")
local StartEventsEvent = require("app.scripts.events.StartEventsEvent")
local AutoPatrolEvent = require("app.scripts.events.AutoPatrolEvent")
local LoopRandomEventEvent = require("app.scripts.events.LoopRandomEventEvent")
local Task = require("app.public.dao.Task")

--动画模块
local DBAniEventType = require("dragonbones.AnimationEventType")

local DoEventHandler = {}

DoEventHandler.SKIP_EVENTS = false
DoEventHandler.SKIP_FACTOR = 5
DoEventHandler.SHOW_NPC_IDS = {}
DoEventHandler.ORIGINAL_NPC_VISIBLE = {}
DoEventHandler.PLAY_SOUND_IDS = {}
DoEventHandler.ANI_IDS = {}

DoEventHandler.Ox = 0 -- 操作点X坐标

function DoEventHandler.init()

end

function DoEventHandler.setLaunchController(controller)
	DoEventHandler.LaunchController = controller
end

function DoEventHandler.getController()
    return DoEventHandler.LaunchController
end

function DoEventHandler.setActionNode(actionNode)
    DoEventHandler._actionNode = actionNode
end

function DoEventHandler.getActionNode()
    return DoEventHandler._actionNode
end

function DoEventHandler.stopNodeActions()
    if DoEventHandler._actionNode then
        DoEventHandler._actionNode:stopAllActions()
    end
end

function DoEventHandler.setSkipEvents(isSkip)
    DoEventHandler.SKIP_EVENTS = isSkip
end

function DoEventHandler.isSkipEvents()
    return DoEventHandler.SKIP_EVENTS
end

function DoEventHandler.setDoingEvents(isDoing)
    DoEventHandler.mDoingEvents = isDoing
end

function DoEventHandler.isDoingEvents()
    return DoEventHandler.mDoingEvents
end

function DoEventHandler.setTracking(tracking)
    DoEventHandler.mTracking = tracking
end

function DoEventHandler.isTracking()
    return DoEventHandler.mTracking
end

function DoEventHandler.setOpenUI(openUi)
    DoEventHandler.mOpenUi = openUi
end

function DoEventHandler.isOpenUI()
    return DoEventHandler.mOpenUi
end

function DoEventHandler.setTaskMaskFlag(flag)
    DoEventHandler.mTaskMaskFlag = flag
end

function DoEventHandler.isTaskMaskFlag()
    return DoEventHandler.mTaskMaskFlag
end

function DoEventHandler.getCharacter()
    local character = FieldManager:getPuppetCharacter()
    if not character then
        character = FieldManager:getMyCharacter()
    end
    return character
end

-- 模拟剧情
function DoEventHandler.testSimulationTaskStory(taskId)
    if not taskId then return end
    -- 加载任务对应的脚本
    local task = Task.new()
    task.id = taskId
    task.conf = GD:queryTaskById(taskId)
    ScriptManager:parseTaskScripts(task)

    local script = ScriptManager:getTaskScript(taskId)
    if not script then return end

    DoEventHandler.isSimulation = true

    local function startSimulation()
        local targetX = 0
        local npcId = tonumber(script.anchorNpc)
        if npcId == 0 then
            targetX = FieldManager:getCharacterX()
        else
            local npc = NpcManager:getNpcById(npcId)
            if npc then
                targetX = npc:getPositionX()
            else
                local npcC = NpcManager:getNpcConfigById(npcId)
                if npcC then
                    targetX = tonumber(npcC.coordinate) or 0
                end
            end
        end

        -- 把人物tp到对应位置
        FieldManager:adjustSelfToFixedPosition(targetX)

        if script.events and script.events:size() > 0 then
            DoEventHandler.startSingleTaskEvents(taskId)
        else
            DoEventHandler.startSingleFollowUpTaskEvents(taskId)
        end 
        
        DoEventHandler.isSimulation = nil
    end

    if script.mapId ~= MapManager:getMapId() then
        MapManager:gotoMap({mapId=script.mapId, service=true, ignoreAni = true})

        local handle = EM:on("onLoadingComp", function()
            FieldManager:setStopSendPosition(true)
            local seq = cc.Sequence:create(cc.DelayTime:create(0.5), cc.CallFunc:create(startSimulation))
            DoEventHandler._actionNode:runAction(seq)

            EM:remove(handle)
        end)

    else
        startSimulation()
    end

end

function DoEventHandler.startDungeonSubEvent(battleId, cb)
    local script = ScriptManager:getDungeonSubScript(battleId)
    if not script then
        executeFunc(cb)
        return
    end
    DoEventHandler._dungeonSubBattleFunc = cb
    DoEventHandler.startTaskEvents({events = script.events,mapId = script.mapId, anchorNpc = 0})
end


function DoEventHandler.startSingleTaskEvents(taskId)
    local script = ScriptManager:getTaskScript(taskId)
    if not script then
        TaskManager:C2S_TaskTalkRequest(taskId)
        return
    end

    DoEventHandler.startTaskEvents({events = script.events,mapId = script.mapId,ox = script.ox,taskId = script.taskId,anchorNpc = script.anchorNpc},true)
end

function DoEventHandler.startSingleFollowUpTaskEvents(taskId)
    local script = ScriptManager:getTaskScript(taskId)
    if script and script.bEvents then

        DoEventHandler.startTaskEvents({events = script.bEvents,mapId = script.mapId,ox = script.ox,taskId = script.taskId,anchorNpc = script.anchorNpc},false)
    else
        TaskManager:storyGetTaskReward(taskId)
    end
end

function DoEventHandler.startTaskEvents(eventsTab,isFront)
    if not eventsTab then return end
    if eventsTab.mapId ~= MapManager:getMapId() then return end
    local taskId = eventsTab.taskId
    if eventsTab.events and eventsTab.events:size() > 0 then
        DoEventHandler.Ox = 0

        local npcId = tonumber(eventsTab.anchorNpc)
        if npcId == nil then
            -- do nothing
        elseif npcId == 0 then
            eventsTab.ox = FieldManager:getCharacterX()
        else
            local npc = NpcManager:getNpcById(npcId)
            if npc then
                eventsTab.ox = npc:getPositionX()
            else
                local npcC = NpcManager:getNpcConfigById(npcId)
                if npcC then
                    eventsTab.ox = tonumber(npcC.coordinate) or 0
                end
            end
        end

        -- 设置坐标
        if eventsTab.ox then
            DoEventHandler.Ox = eventsTab.ox
        end

        DoEventHandler.startEvents(eventsTab.events)
    elseif isFront then
        TaskManager:C2S_TaskTalkRequest(taskId)
    end

    if isFront then
        DoEventHandler.FrontEvent = true
    else
        DoEventHandler.FrontEvent = false
    end
end

function DoEventHandler.isFrontEvents()
    return DoEventHandler.FrontEvent
end

function DoEventHandler.startEvents(eventsVec,npcId)
    if eventsVec == nil or eventsVec:size() <= 0 then
        return
    end
    DoEventHandler.mStartEventTime = app.session:getServerTime()
    -- UIHandler:blackScreenFade("fadeOut",0)
    DoEventHandler.setDoingEvents(true)
    DoEventHandler.mDoingEventsVec = eventsVec
    DoEventHandler.mCurrentEventsVecIndex = 1
    DoEventHandler.mCurrentEvent = nil
    DoEventHandler.mCurrentEventsVec = DoEventHandler.getCurrentEventsVec()
    if npcId ~= nil then
        DoEventHandler.mCurrentEventNpcId = npcId
    end
    DoEventHandler._doSkipOperate = false
    DoEventHandler._talkAudioOver = true

    FieldManager:hideAllBubble()

    DoEventHandler.doEventsVec(DoEventHandler.mCurrentEventsVec)
end

function DoEventHandler.getCostTime()
    local costTime = 0
    if DoEventHandler.mStartEventTime then
        costTime = app.session:getServerTime() - DoEventHandler.mStartEventTime
    end
    return costTime
end

function DoEventHandler.clearEventsStatus()
    DoEventHandler.mCurrentEvent = nil
    DoEventHandler.mDoingEventsVec = nil
    DoEventHandler.mCurrentEventsVec = nil
    DoEventHandler.mCurrentEventsVecIndex = 1
    DoEventHandler.setTracking(false)
    DoEventHandler.setDoingEvents(false)
    DoEventHandler.setAutoPatrolForever(false)
    DoEventHandler.setTalkAudioId(nil)
    DoEventHandler.setGoMapId(nil)
    DoEventHandler.removeCloud()
end

function DoEventHandler.findBattleOrTaskFinishIndex()

    local function getIndexByEventName(name)
        local vecSize = DoEventHandler.mDoingEventsVec:size()
        for i = 1, vecSize do
            local eventsVec = DoEventHandler.mDoingEventsVec:get(i)
            local size = eventVec:size()
            for j = 1, size do
                local event = eventsVec:get(j)
                local eventName = ""
                if event then
                    eventName = event:getEventName()
                end
                if eventName == name then
                    return i
                end
            end
        end
        return 0
    end

    local index = getIndexByEventName("TASK_FINISH_EVENT")
    if index == 0 then
        index = getIndexByEventName("TASK_BATTLE_EVENT")
        if index == 0 then
            index = getIndexByEventName("TASK_BATTLE_TILL_OVER_EVENT")
            if index == 0 then
                index = getIndexByEventName("COMMON_BATTLE_EVENT")
            end
        end
    end

    return index
end

function DoEventHandler.getCurrentEventNpcId()
    return DoEventHandler.mCurrentEventNpcId
end

function DoEventHandler.isNextCloudEvent()
    local vec = nil
    if DoEventHandler.mDoingEventsVec ~= nil and DoEventHandler.mDoingEventsVec:size() > 0 then
        local size = DoEventHandler.mDoingEventsVec:size()
        local nextIndex = DoEventHandler.mCurrentEventsVecIndex
        if nextIndex <= size then
            vec = DoEventHandler.mDoingEventsVec:get(nextIndex)
        end
    end
    if vec then
        local size = vec:size()
        for i = 1, size do
            local event = vec:get(i)
            if event then
                if event:getEventName() == event.CLOUD_EVENT then
                    return true
                end
            end
        end
    end
    return false
end

function DoEventHandler.getCurrentEventsVec()
    local vec = nil
    if DoEventHandler.mDoingEventsVec == nil or DoEventHandler.mDoingEventsVec:size() <= 0 then
        return vec
    end

    local size = DoEventHandler.mDoingEventsVec:size()
    if DoEventHandler.mCurrentEventsVecIndex <= size then
        vec = DoEventHandler.mDoingEventsVec:get(DoEventHandler.mCurrentEventsVecIndex)
        DoEventHandler.mCurrentEventsVecIndex = DoEventHandler.mCurrentEventsVecIndex + 1
    end
    return vec
end

function DoEventHandler.foreCurrentEventsOver()
    if not DoEventHandler.mCurrentEventsVec then
        return
    end
    local size = DoEventHandler.mCurrentEventsVec:size()
    for i = 1, size do
        local event = DoEventHandler.mCurrentEventsVec:get(i)
        if event then
            event:setAlive(false)
            event:stop()
        end
    end
    DoEventHandler.mCurrentEvent = nil
    DoEventHandler.updateNextEventsVec()
end

function DoEventHandler.forceNextEventsVec()
    if not DoEventHandler.mCurrentEventsVec then
        return
    end
    DoEventHandler.updateNextEventsVec()
end

function DoEventHandler.setTalkTouchOver(touch)
    DoEventHandler.mTalkTouchOver = touch
end

function DoEventHandler.getTalkTouchOver()
    return DoEventHandler.mTalkTouchOver
end

function DoEventHandler.overCurrentTalkEvent()
    if not DoEventHandler.mCurrentEventsVec then
        return
    end
    local size = DoEventHandler.mCurrentEventsVec:size()
    for i = 1, size do
        local event = DoEventHandler.mCurrentEventsVec:get(i)
        if event and event:getEventName() == event.TALK_EVENT then
            if event:getTag() == 0 then
                FieldManager:hideAllBubble()
                event:setAlive(false)
                event:stop()
            end
        end
    end
    local curAudioId = DoEventHandler.getTalkAudioId()
    if curAudioId then
        AM.stop(curAudioId)
        DoEventHandler.setTalkAudioId(nil)
    end
    DoEventHandler.updateNextEventsVec()
end

function DoEventHandler.setTalkAudioId(audioId)
    DoEventHandler.mTalkAudioId = audioId
end

function DoEventHandler.getTalkAudioId()
    return DoEventHandler.mTalkAudioId
end

function DoEventHandler.overCouldSkipEvent()
    if not DoEventHandler.mCurrentEventsVec then
        return
    end
    local size = DoEventHandler.mCurrentEventsVec:size()
    for i = 1, size do
        local event = DoEventHandler.mCurrentEventsVec:get(i)
        if event then
            if event:getEventName() == event.TALK_EVENT or event:getEventName() == event.HEART_WORDS_EVENT then
                if event:getEventName() == event.TALK_EVENT then
                    if event:getTag() == 0 then
                        FieldManager:hideAllBubble()
                    end
                end
                if event:getTag() == 0 then
                    event:setAlive(false)
                    event:stop()
                end
            end
        end
    end
    DoEventHandler.updateNextEventsVec()
end

function DoEventHandler.getSkipStartIndex()
    local index = -1
    if DoEventHandler.mDoingEventsVec == nil or DoEventHandler.mDoingEventsVec:size() <= 0 then
        return index
    end

    local vecSize = DoEventHandler.mDoingEventsVec:size()
    for i = 1, vecSize do
        local vec = DoEventHandler.mDoingEventsVec:get(i)
        local size = vec:size()
        for j = 1, size do
            local event = vec:get(j)
            if event then
                local name = event:getEventName()
                if name == event.SKIP_FLAG_START_EVENT then
                    index = i
                    return index
                end
            end
        end
    end
    return index
end

function DoEventHandler.getSkipEndIndex()
    local index = -1
    if DoEventHandler.mDoingEventsVec == nil or DoEventHandler.mDoingEventsVec:size() <= 0 then
        return index
    end

    local vecSize = DoEventHandler.mDoingEventsVec:size()
    for i = 1, vecSize do
        local vec = DoEventHandler.mDoingEventsVec:get(i)
        local size = vec:size()
        for j = 1, size do
            local event = vec:get(j)
            if event then
                local name = event:getEventName()
                if name == event.SKIP_FLAG_EVENT and not event:isStart() then
                    index = i
                    return index
                end
            end
        end
    end
    return index
end

function DoEventHandler.skipToEnd()
    UIHandler:blackScreenFade("fadeOut",0)
    local endIndex = DoEventHandler.getSkipEndIndex()
    if endIndex ~= -1 then
        DoEventHandler.mCurrentEventsVecIndex = endIndex
        DoEventHandler.foreCurrentEventsOver()
    end
    DoEventHandler._doSkipOperate = true
    DoEventHandler.stopMapShakeAction()
end

function DoEventHandler.isSyncEventsOver(syncEventsVec)
    if syncEventsVec == nil or syncEventsVec:size() <= 0 then
        return false
    end

    local isOver = true

    local size = syncEventsVec:size()
    for i = 1, size do
        local event = syncEventsVec:get(i)
        if event and event:isAlive() then
            isOver = false
        end
    end

    return isOver
end


function DoEventHandler.setEventEnd(event)
    if event ~= nil then
        event:setAlive(false)
        event:stop()
    end
    if event == DoEventHandler.mCurrentEvent then
        DoEventHandler.mCurrentEvent = nil
    end
end

function DoEventHandler.updateNextEventsVec()
    if DoEventHandler.mCurrentEventsVec == nil or DoEventHandler.mCurrentEventsVec:size() <= 0 then
        DoEventHandler.mCurrentEventsVec = DoEventHandler.getCurrentEventsVec()
        if DoEventHandler.mCurrentEventsVec == nil or DoEventHandler.mCurrentEventsVec:size() <= 0 then
            return false
        else
            DoEventHandler.doEventsVec(DoEventHandler.mCurrentEventsVec)
            return true
        end
    else
        if DoEventHandler.isSyncEventsOver(DoEventHandler.mCurrentEventsVec) then
            if DoEventHandler.mDoingEventsVec == nil or DoEventHandler.mCurrentEventsVecIndex > DoEventHandler.mDoingEventsVec:size() then
                DoEventHandler.mDoingEventsVec = nil
                DoEventHandler.mCurrentEventsVec = nil

                DoEventHandler.setDoingEvents(false)
                DoEventHandler.setTracking(false)
                DoEventHandler.setOpenUI(false)
                FieldManager:characterForceStandby()
                FieldManager:completeEvent()
                NpcManager:allNpcStandBy()
                --print("events done")
                --事件结束 返回正常状态
                return false
            end

            DoEventHandler.mCurrentEventsVec = nil
            DoEventHandler.mCurrentEventsVec = DoEventHandler.getCurrentEventsVec()
            DoEventHandler.doEventsVec(DoEventHandler.mCurrentEventsVec)
            return true
        else
            return true
        end
    end
    return false
end



function DoEventHandler.doEventsVec(eventsVec)
    if eventsVec == nil or eventsVec:size() <= 0 then
        -- self:setEventEnd(self.mCurrentEvent)
        -- self:updateNextEventsVec()
        DoEventHandler.foreCurrentEventsOver()
    else
        FieldManager:hideAllBubble()

        local size = eventsVec:size()

        -- 先把当前要执行的所有事件的alive设置为true（不能放在doEvent里）
        for i = 1, size do 
            local event  = eventsVec:get(i)
            if event then event:setAlive(true) end
        end

        for i = 1, size do
            local event = eventsVec:get(i)
            DoEventHandler.doEvent(event)
        end
    end
end

function DoEventHandler.nextEventsVec(curEvent)
    if not BattleManager:isBattle() then
        if curEvent then
            DoEventHandler.setEventEnd(curEvent)
            return DoEventHandler.updateNextEventsVec()
        elseif DoEventHandler.mCurrentEvent then
            DoEventHandler.setEventEnd(DoEventHandler.mCurrentEvent)
            return DoEventHandler.updateNextEventsVec()
        end
    end
    return false
end

function DoEventHandler.setTouchForNextTalk(touch)
    DoEventHandler.mTouchForNextTalk = touch
end

function DoEventHandler.isTouchForNextTalk()
    return DoEventHandler.mTouchForNextTalk
end

function DoEventHandler.doEvent(event)
    if not event then return end
    local eventName = event:getEventName()

    -- event:setAlive(true)
    DoEventHandler.mCurrentEvent = event

    -- print("doEvent eventName = ",eventName)
    if eventName == event.TALK_EVENT then
        DoEventHandler.doTalkEvent(event)
    elseif eventName == event.HEART_WORDS_EVENT then
        DoEventHandler.doHeartWordsEvent(event)
    elseif eventName == event.STORY_MODE_EVENT then
        DoEventHandler.doStoryModeEvent(event)
    elseif eventName == event.TASK_FINISH_EVENT then
        DoEventHandler.doTaskFinishEvent(event)
    elseif eventName == event.ASK_FOR_SPECIAL_TASK_EVENT then
        DoEventHandler.doAskForSpecialTaskEvent(event)
    elseif eventName == event.CHANGE_MAP_EVENT then
        DoEventHandler.doChangeMapEvent(event)
    elseif eventName == event.WALK_EVENT then
        DoEventHandler.doWalkEvent(event)
    elseif eventName == event.START_EVENTS_EVENT then
        DoEventHandler.doStartEventsEvent(event)
    elseif eventName == event.TASK_BATTLE_EVENT then
        DoEventHandler.doTaskBattleEvent(event)
    elseif eventName == event.TASK_BATTLE_TILL_OVER_EVENT then
        DoEventHandler.doTaskBattleTillOverEvent(event)
    elseif eventName == event.COMMON_BATTLE_EVENT then
        DoEventHandler.doCommonBattleEvent(event)
    elseif eventName == event.EVENTS_FINISH_EVENT then
        DoEventHandler.doEventsFinishEvent(event)
    elseif eventName == event.AUTO_PATROL_EVENT then
        DoEventHandler.doAutoPatrolEvent(event)
    elseif eventName == event.ANI_PLAY_EVENT then
        DoEventHandler.doAniPlayEvent(event)
    elseif eventName == event.ANI_MOVE_EVENT then
        DoEventHandler.doAniMoveEvent(event)
    elseif eventName == event.DELETE_ANI_EVENT then
        DoEventHandler.doDeleteAniEvent(event)
    elseif eventName == event.SOUND_CONTROL_EVENT then
        DoEventHandler.doSoundControlEvent(event)
    elseif eventName == event.PLAY_SOUND_EVENT then
        DoEventHandler.doPlaySoundEvent(event)
    elseif eventName == event.STOP_SOUND_EVENT then
        DoEventHandler.doStopSoundEvent(event)
    elseif eventName == event.SHOW_NPC_EVENT then
        DoEventHandler.doShowNpcEvent(event)
    elseif eventName == event.FOCUS_TRANS_EVENT then
        DoEventHandler.doFocusTransEvent(event)
    elseif eventName == event.NPC_JUMP_EVENT then
        DoEventHandler.doNpcJumpEvent(event)
    elseif eventName == event.CAMERA_MOVE_EVENT then
        DoEventHandler.doCameraMoveEvent(event)
    elseif eventName == event.RELATIVE_CAMERA_MOVE_EVENT then
        DoEventHandler.doRelativeCameraMoveEvent(event)
    elseif eventName == event.WAIT_EVENT then
        DoEventHandler.doWaitEvent(event)
    elseif eventName == event.NPC_DIRECTION_EVENT then
        DoEventHandler.doNpcDirectionEvent(event)
    elseif eventName == event.CAMERA_ZOOM_EVENT then
        DoEventHandler.doCameraZoomEvent(event)
    elseif eventName == event.CAMERA_ZOOM_TO_EVENT then
        DoEventHandler.doCameraZoomToEvent(event)
    elseif eventName == event.NPC_MOVE_EVENT then
        DoEventHandler.doNpcMoveEvent(event)
    elseif eventName == event.RANDOM_EVENT then
        DoEventHandler.doRandomEvent(event)
    elseif eventName == event.LOOP_RANDOM_EVENT_EVENT then
        DoEventHandler.doLoopRandomEventEvent(event)
    elseif eventName == event.PLAY_ACTION_EVENT then
        DoEventHandler.doPlayActionEvent(event)
    elseif eventName == event.DELETE_NPC_EVENT then
        DoEventHandler.doDeleteNpcEvent(event)
    elseif eventName == event.NPC_VISIBILITY_EVENT then
        DoEventHandler.doNpcVisibilityEvent(event)
    elseif eventName == event.CAMERA_BACKTO_ORIGIN then
        DoEventHandler.doCameraBackToOrigin(event)
    elseif eventName == event.MONSTER_CALL_EVENT then
        DoEventHandler.doMonsterCallEvent(event)
    elseif eventName == event.EXCLAM_MARK_EVENT then
        DoEventHandler.doExclamMarkEvent(event)
    elseif eventName == event.TASK_MARK_VISIBILITY_EVENT then
        DoEventHandler.doTaskMarkVisibilityEvent(event)
    elseif eventName == event.NPC_FADE_EVENT then
        DoEventHandler.doNpcFadeEvent(event)
    elseif eventName == event.SIGN_MARK_EVENT then
        DoEventHandler.doSignMarkEvent(event)
    elseif eventName == event.TASK_GATHER_EVENT then
        DoEventHandler.doTaskGatherEvent(event)
    elseif eventName == event.GATHER_CONDITIONAL_EVENT then
        DoEventHandler.doGatherConditionalEvent(event)
    elseif eventName == event.GATHER_ACTION_EVENT then
        DoEventHandler.doGatherActionEvent(event)
    elseif eventName == event.GATHER_UI_CALL_EVENT then
        DoEventHandler.doGatherUICallEvent(event)
    elseif eventName == event.GATHER_CONTROL_EVENT then
        DoEventHandler.doGatherControlEvent(event)
    elseif eventName == event.GATHER_TO_POINT_EVENT then
        DoEventHandler.doGatherToPointEvent(event)
    elseif eventName == event.SET_STONE_EVENT then
        DoEventHandler.doSetStoneEvent(event)
    elseif eventName == event.GET_ON_RIDE_EVENT then
        DoEventHandler.doGetOnRideEvent(event)
    elseif eventName == event.GET_OFF_RIDE_EVENT then
        DoEventHandler.doGetOffRideEvent(event)
    elseif eventName == event.GET_RIDE_EVENT then
        DoEventHandler.doGetRideEvent(event)
    elseif eventName == event.NPC_FACETO_MAIN_EVENT then
        DoEventHandler.doFaceToMainEvent(event)
    elseif eventName == event.MAIN_FACETO_NPC_EVENT then
        DoEventHandler.doMainFaceToNpcEvent(event)
    elseif eventName == event.TASK_LOOP_UI_EVENT then
        DoEventHandler.doTaskLoopUIEvent(event)
    elseif eventName == event.PRESTIGE_DONATE_UI_EVENT then
        DoEventHandler.doPrestigeDonateUIEvent(event)
    elseif eventName == event.PRESTIGE_SHOP_UI_EVENT then
        DoEventHandler.doPrestigeShopUIEvent(event)
    elseif eventName == event.BLACK_SCREEN_EVENT then
        DoEventHandler.doBlackScreenEvent(event)
    elseif eventName == event.FADE_SCREEN_EVENT then
        DoEventHandler.doFadeScreenEvent(event)
    elseif eventName == event.MAP_SHAKE_EVENT then
        DoEventHandler.doMapShakeEvent(event)
    elseif eventName == event.COMMON_UI_EVENT then
        DoEventHandler.doCommonUIEvent(event)
    elseif eventName == event.TYPE_WORDS_EVENT then
        DoEventHandler.doTypeWordsEvent(event)
    elseif eventName == event.FADE_WORDS_EVENT then
        DoEventHandler.doFadeWordsEvent(event)
    elseif eventName == event.MAP_ZOOM_EVENT then
        DoEventHandler.doMapZoomEvent(event)
    elseif eventName == event.SKIP_OPERATE_EVENT then
        DoEventHandler.doSkipOperateEvent(event)
    elseif eventName == event.CLOUD_EVENT then
        DoEventHandler.doCloudEvent(event)
    elseif eventName == event.TRANSFORM_EVENT then
        DoEventHandler.doTransformEvent(event)
    elseif eventName == event.HEARTH_STONE_EVENT then
        DoEventHandler.doHearthStoneEvent(event)
    elseif eventName == event.DISASTER_BATTLE_EVENT then
        DoEventHandler.doDisasterBattleEvent(event)
    elseif eventName == event.SKIP_FLAG_START_EVENT then
        DoEventHandler.doSkipFlagStartEvent(event)
    elseif eventName == event.SKIP_FLAG_END_EVENT then
        DoEventHandler.doSkipFlagEndEvent(event)
    elseif eventName == event.SKIP_FLAG_EVENT then
        DoEventHandler.doSkipFlagEvent(event)
    elseif eventName == event.CAMERA_BACKTO_MAX_EVENT then
        DoEventHandler.doCameraBackToMaxEvent(event)
    elseif eventName == event.DESKTOP_VISIBILITY_EVENT then
        DoEventHandler.doDesktopVisibilityEvent(event)
    elseif eventName == event.STORY_BRANCH_EVENT then
        DoEventHandler.doStoryBranchEvent(event)
    elseif eventName == event.CREATE_PUPPET_EVENT then
        DoEventHandler.doCreatePuppetEvent(event)
    elseif eventName == event.DELETE_PUPPET_EVENT then
        DoEventHandler.doDeletePuppetEvent(event)
    elseif eventName == event.WEATHER_CONTROL_EVENT then
        DoEventHandler.doWeatherControlEvent(event)
    elseif eventName == event.CHECK_TASK_ITEM_EVENT then
        DoEventHandler.doCheckTaskItemEvent(event)
    elseif eventName == event.FUNCTION_LEVELUP_EVENT then
        -- 废弃
    elseif eventName == event.VIDEO_PLAY_EVENT then
        DoEventHandler.doVideoPlayEvent(event)
    elseif eventName == event.RETURN_LAST_MAP_EVENT then
        -- 废弃
    elseif eventName == event.MOVE_TO_NPC_EVENT then
        DoEventHandler.doMoveToNpcEvent(event)
    elseif eventName == event.COUNT_DOWN_EVENT then
        DoEventHandler.doCountDownEvent(event)
    elseif eventName == event.SCENE_MASK_EVENT then
        DoEventHandler.doSceneMaskEvent(event)
    elseif eventName == event.SINGLE_NPC_MASK_EVENT then
        DoEventHandler.doSingleNpcMaskEvent(event)
    elseif eventName == event.RESET_SCENE_MASK_EVENT then
        DoEventHandler.doResetSceneMaskEvent(event)
    elseif eventName == event.ENTER_DUNGEON_EVENT then
        DoEventHandler.doEnterDungeonEvent(event)
    elseif eventName == event.TRANSFER_STATUS_EVENT then
        DoEventHandler.doTransferStatusEvent(event)
    elseif eventName == event.SHOW_TV_TESTING_EVENT then
        DoEventHandler.doShowTvTestingEvent(event)
    elseif eventName == event.TRANSFER_IN_SAME_MAP_EVENT then
        DoEventHandler.doTransferInSameMapEvent(event)
    end

    DoEventHandler.setTalkTouchOver(false)
end

local function moveToEventsPoint(npc)
    if StoryManager:isEnterStoryMode() then
        return
    end
    local character = DoEventHandler.getCharacter()

    local eventRange = npc:getEventRange()
    if eventRange then
        local lx = eventRange.tlx
        local rx = eventRange.trx
        local nx = eventRange.nx
        local cx = math.floor(character:getPositionX())

        if cx >= lx and cx <= rx then
        else
            local targetX = cx
            if cx < nx then
                --to left
                targetX = math.floor(lx)
            else
                --to right
                targetX = math.floor(rx)
            end

            if targetX ~= cx then
                character:setTargetX(targetX,function()
                    character:faceTo(nx)
                end)
            end
        end
    end

end

function DoEventHandler.doTalkEvent(event)
    local npcId = event.mNpcId
    local content = event.mContent
    local showTime = event.mTime
    local maskTime = event.mMaskTouchTime
    local soundPath = event.mSoundPath
    local actionName = event.mActionName
    local soundId = event.mSoundId
    local delayTime = event.mDelayTime
    local showType = event.mShowType

    event:setTag(1)

    if DoEventHandler.isSkipEvents() then
        showTime = showTime / DoEventHandler.SKIP_FACTOR
    end

    local function excute()
        if soundId and DoEventHandler._talkAudioOver then
            DoEventHandler._talkAudioOver = false
            AM.playSoundById(soundId,function()
                DoEventHandler._talkAudioOver = true
            end)
            DoEventHandler.setTalkAudioId(soundId)
        end

        DoEventHandler.setTouchForNextTalk(false)

        if not StoryManager:isEnterStoryMode() then
            MapManager:fadeMapNode({time = 0.5,back = false})
        end

        local function call()
            if not StoryManager:isEnterStoryMode() then
                MapManager:fadeMapNode({time = 0.5,back = true})
            end
            DoEventHandler.setTalkAudioId(nil)
            DoEventHandler.nextEventsVec(event)
        end

        if npcId == 0 then--主角
            local character = DoEventHandler.getCharacter()

            character:showBubble(content,showTime,call)
            character:setBubbleEndCallback(function()
                call()
            end)
            if actionName and string.len(actionName) > 0 then
                character:playEventsAction(actionName)
            end
        else
            local npc = NpcManager:getNpcById(npcId)
            if npc then
                npc:showBubble(content,showTime,call)
                npc:setBubbleEndCallback(function()
                    call()
                end)
                if actionName and string.len(actionName) > 0 then
                    if actionName ~= npc:getCurAction() then
                        npc:playEventAction(actionName)
                    end
                end
                if DoEventHandler.getTalkTouchOver() then
                    moveToEventsPoint(npc)
                end
            else
                call()
            end
        end

        event:setStopCall(function()
            if not StoryManager:isEnterStoryMode() then
                MapManager:fadeMapNode({time = 0.5,back = true})
            end
        end)
    end

    if delayTime > 0 then
         DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(delayTime),
                cc.CallFunc:create(excute)))
    else
        excute()
    end


end

function DoEventHandler.doHeartWordsEvent(event)
    local content = event.mContent
    local time = event.mTime
    local showDirection = event.mShowDirection
    local showType = event.mShowType
    local delayTime = event.mDelayTime

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end
    event:setTag(1)

    local function excute()
        UIHandler:HeartWordsViewVisibility(true,content,time,showDirection,callOver)
        local hasCall = false
        local function callOver()
            if hasCall then return end
            hasCall = true
            UIHandler:HeartWordsViewVisibility(false)
            DoEventHandler.nextEventsVec(event)
        end
        UIHandler:HeartWordsViewVisibility(true,content,time,showDirection,callOver)
    end

    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(delayTime),
                cc.CallFunc:create(excute)))
    else
        excute()
    end

end

function DoEventHandler.doStoryModeEvent(event)
    local enter = event.mEnter
    local npcId = event.mNpcId
    local time = event.mTime
    local fadeTime = event.mFadeTime
    local hideBorder = event.mHideBorder
    local taskId = event.mTaskId
    local mask = event.mMask
    local dungeonSubFlag = event.mDungeonSubFlag

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end


    if enter then
        if fadeTime then
            StoryManager:enterStoryMode(npcId,time,true,event)
            UIHandler:blackScreenFade("fadeIn",fadeTime,function()
                DoEventHandler.nextEventsVec(event)
                UIHandler:hideDesktop()
                StoryManager:showMask(nil,0,false)
            end)
        else
            StoryManager:enterStoryMode(npcId,time,hideBorder,event,function()
                DoEventHandler.nextEventsVec(event)
            end)
        end
    else
        if not dungeonSubFlag then
            DoEventHandler.setTaskMaskFlag(true) -- 添加屏蔽主线任务追踪的状态，等接到新的主线任务的时候再移除
        end

        if not DoEventHandler._doSkipOperate and taskId then
            app.session:request("action.C2S_PlotWatch",{questId = taskId,result = 1,watchTime = DoEventHandler.getCostTime()})
        end

        if fadeTime then
            StoryManager:exitStoryMode(npcId,time)
            UIHandler:blackScreenFade("fadeOut",fadeTime,nil,function()
                StoryManager:clearStoryStatus(event)
            end)
        else
            StoryManager:exitStoryMode(npcId,time,function()
                StoryManager:clearStoryStatus(event)
            end)
        end
        DoEventHandler.stopNodeActions()

        -- 如果是战斗的剧情
        if dungeonSubFlag then
            executeFunc(DoEventHandler._dungeonSubBattleFunc)
            DoEventHandler._dungeonSubBattleFunc = nil
        end
    end

    if mask then
        UIHandler:showBlackScreenMask()
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(cc.DelayTime:create(5),
                cc.CallFunc:create(function()
                    UIHandler:removeBlackScreenMask()
        end)))
    else
        UIHandler:removeBlackScreenMask()
    end
end

function DoEventHandler.doTaskFinishEvent(event)
    local taskId = event.taskId
    local clearNpcId = event.clearNpcId
    local endContentId = event.contentId
    local uid = nil

    local npc = NpcManager:getNpcById(clearNpcId)
    if npc then
        npc:removeEventsFirstElement()

        uid = npc:getUid()
    else
        local area = NpcManager:getArea(clearNpcId)
        if area then
            area:clearEvents()
            uid = area:getUid()
        end
    end

    TaskManager:C2S_TaskTalkRequest(taskId)

    DoEventHandler.nextEventsVec(event)

end

function DoEventHandler.doAskForSpecialTaskEvent(event)
    local taskType = event.mTaskType
    local npcId = event.mNpcId
    local uid = nil
    local npc = NpcManager:getNpcById(npcId)
    if npc then
        npc:removeEventsFirstElement()

        uid = npc:getUid()
    else
        local area = NpcManager:getArea(npcId)
        if area then
            area:clearEvents()
            uid = area:getUid()
        end
    end

    app.session:notify("action.C2S_AskForQuest",{questType = taskType,npcUid = uid,npcId = npcId})

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doChangeMapEvent(event)
    local mapId = event.mMapId
    local pop = event.mPop
    local transNpcId = event.mTransNpcId
    local confirmNpcId = event.mConfirmNpcId
    local nextEvent = event.mNextEvent

    if mapId and mapId == MapManager:getMapId() then
        DoEventHandler.nextEventsVec()
        return 
    end

    if pop then

    else
        if DoEventHandler.getGoMapId() then
            mapId = DoEventHandler.getGoMapId()
            DoEventHandler.setGoMapId(nil)
            transNpcId = nil
        end

        local curMapId = MapManager:getMapId()
        local mapConf = GD:queryMapById(curMapId)
        if DungeonManager:isCrossDungeon() then
            -- 跨服副本，直接退出副本
            DungeonManager:leaveDungeonRequest()
        elseif mapConf.maptype == "2" then
            -- 当前是地下城副本，点击传送地图的npc，肯定是退出副本，使用特殊逻辑退出副本
            DungeonManager:leaveDungeonRequest()
        else
            local params = {}
            params.mapId = mapId
            params.confirmNpcId = confirmNpcId
            params.transNpcId = transNpcId
            app:dispatchCustomEvent("EVENT_CHANGE_MAP", params)
        end

        if nextEvent then
            DoEventHandler.nextEventsVec(event)
        end
    end

end

function DoEventHandler.doWalkEvent(event)
    local dx = event.mDx
    local dy = event.mDy
    if FieldManager:getMyCharacter() then
        FieldManager:getMyCharacter():autoWayFinding(dx)
    end
end

function DoEventHandler.doStartEventsEvent(event)
    local npcId = event.mNpcId
    local taskId = event.mTaskId

    local npc = NpcManager:getNpcById(npcId)
    if npc then
        -- 和NpaManager:markClick同步
        if npc:getMarkType() == "gather" then
            npc:addEventsAt(1,St.createTaskGatherEvents(npc:getId(), npc:getUid()))
        end
        npc:setPlayEvents(true)
        npc:setDoingEvents(true)
        FieldManager:setTrackDoing(true)
    end
    DoEventHandler.setTracking(false)
end
--enum Difficulty {easy = 0;normal = 1;hard = 2;}
function DoEventHandler.setBattleDifficulty(difficulty)
    DoEventHandler.BATTLE_DIFFICULTY = difficulty
end

function DoEventHandler.getBattleDifficulty()
    return DoEventHandler.BATTLE_DIFFICULTY
end

function DoEventHandler.doTaskBattleEvent(event)
    local immediately = event.mImmediately
    local npcId = event.mNpcId
    local npcUid = 0
    local deleteContent = event.mDeleteContent
    local battleDir = event.mBattleDir

    DoEventHandler.DoTaskBattleEvent = true
    DoEventHandler.CurTaskBattleEvent = event

    local function okCallback()
        UIHandler:hideBattleConfirm()


        local npc = NpcManager:getNpcById(npcId)
        local area = nil
        if npc then
            npcUid = npc:getUid()
        else
            area = NpcManager:getArea(npcId)
            if area then
                npcUid = area:getUid()
            end
        end

        if not npc and not area then
            DoEventHandler.DoTaskBattleEvent = false
            DoEventHandler.nextEventsVec(event)
            return
        end

        local function battleCallback(msg)
            DoEventHandler.setBattleDifficulty(nil)
            BattleManager:handleBattleError(msg)
        end

        BattleManager:battleStart({npcID = npcId,dir = battleDir,callback = battleCallback})
    end

    local function cancelCallback()
        DoEventHandler.skipStoryViewVisibility(true)
        UIHandler:hideBattleConfirm()
        DoEventHandler.nextEventsVec(event)
    end

    if immediately then
        -- DoEventHandler.nextEventsVec(event)

        okCallback()
    else
        DoEventHandler.skipStoryViewVisibility(false)
        UIHandler:showBattleConfirm(okCallback,cancelCallback)
    end
end

function DoEventHandler.doTaskBattleTillOverEvent(event)
    local npcId = event.mNpcId
    local npcUid = 0
    local videoFile = event:getVideoFile(UD.player.classID)
    local battleDir = event.mBattleDir

    DoEventHandler.DoTaskBattleEvent = true
    DoEventHandler.CurTaskBattleEvent = event

    if videoFile and videoFile.formationId and videoFile.file then
        BattleManager:gotoBattle(nil, nil,{formationId = videoFile.formationId,videoFile = videoFile.file, playerUid = videoFile.uid, configDir = videoFile.configDir})
        return
    end

    local npc = NpcManager:getNpcById(npcId)
    local area
    if npc then
        npcUid = npc:getUid()
    else
        area = NpcManager:getArea(npcId)
        if area then
            npcUid = area:getUid()
        end
    end

    if not npc and not area then
        DoEventHandler.DoTaskBattleEvent = false
        DoEventHandler.nextEventsVec(event)
        return
    end

    local function battleCallback(msg)
        DoEventHandler.setBattleDifficulty(nil)
        BattleManager:handleBattleError(msg)
    end

    BattleManager:battleStart({npcID = npcId,dir = battleDir,callback = battleCallback})
end

function DoEventHandler.doCommonBattleEvent(event)
    local npcId = event.mNpcId
    local immediately = event.mImmediately
    local battleDir = event.mBattleDir
    local npcUid = nil

    local function okCallback()

        local npc = NpcManager:getNpcById(npcId)
        if npc then
            npcUid = npc:getUid()
        else
            local area = NpcManager:getArea(npcId)
            if area then
                npcUid = area:getUid()
            end
        end

        DoEventHandler.nextEventsVec(event)
        local function battleCallback(msg)
            DoEventHandler.setBattleDifficulty(nil)
            BattleManager:handleBattleError(msg)
        end

        BattleManager:battleStart({npcID = npcId,dir = battleDir,callback = battleCallback})
    end

    if immediately then
        okCallback()
    end

end

function DoEventHandler.doEventsFinishEvent(event)
    local npcId = event.mNpcId

    local npc = NpcManager:getNpcById(npcId)
    if npc then
        npc:standBy()
    end
    MapManager:pauseRunCameraZoomForEvent(false)
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.setAutoPatrolForever(forever)
    DoEventHandler.AutoPatrolForever = forever
end

function DoEventHandler.isAutoPatrolForever()
    return DoEventHandler.AutoPatrolForever
end

function DoEventHandler.doAutoPatrolEvent(event)
    local center = event.mCenter
    local radius = event.mRadius
    local forever = event.mForever
    DoEventHandler.setAutoPatrolForever(forever)
    if FieldManager:getMyCharacter() then
        FieldManager:getMyCharacter():setAutoPatrol(true,center,radius)
        app:dispatchCustomEvent("EVENT_START_TRACKING_STATUS")
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doAniPlayEvent(event)
    local line = event.mAddLine
    local aniId = event.mAniId
    local nextImmediately = event.mNextImmediately
    local aniDirectory = event.mAniDirectory
    local armatureName = event.mArmatureName
    local playAction = event.mPlayAction
    local posAtNpcId = event.mPosAtNpcId
    local scale = event.mScale
    local zOrder = event.mZOrder
    local keepTime = event.mKeepTime
    local showType = event.mShowType
    local fadeTime = event.mFadeTime
    local delete = event.mDelete
    local preType = event.mPreType

    if delete then
        if preType then
            UIHandler:getStoryModeUi():removeUIByKey("mAniPreLayer"..aniId)
        elseif cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():removeAni(aniId)
        end
        
        DoEventHandler.nextEventsVec(event)
        return
    end

    local Armature = app:getClass("Armature")
    local animation = Armature.create({
        path = aniDirectory,
        armatureName = armatureName,
        animationName = "",
        skeletonName = armatureName,
        textureName = armatureName
    })

    local aniLayer = display.newLayer()
    aniLayer:addChild(animation)
    animation:setPosition(cc.p(0,0))

    local character = DoEventHandler.getCharacter()

    local x = 0
    local y = 0
    if posAtNpcId then
        local posNpc = NpcManager:getNpcById(posAtNpcId)
        if posNpc then
            posNpc:setVisible(false)
            x = posNpc:getPositionX()
            y = posNpc:getPositionY()

            if preType then
                x, y = posNpc:toWorldPosition(cc.p(0, 0))
            end
        end
    else
        x = event.mx + DoEventHandler.Ox
        y = (event.my == 0) and FieldManager:getCharacterY() or event.my

        -- 前层动画
        if preType then 
            --以自己的character为标准 计算动画位置的world position
            local characterX = character:getPositionX()
            local targetX = DoEventHandler.Ox + event.mx - characterX
            x = character:toWorldPosition(cc.p(targetX, 0))
        end
    end

    local cx = character:getPositionX()
    if x > cx then--面向左
        animation:setScaleX(1 * scale)
    else--面向右
        animation:setScaleX(-1 * scale)
    end
    animation:setScaleY(scale)
    aniLayer:setPosition(cc.p(x,y))
    
    if preType then
        UIHandler:getStoryModeUi():addUI("mAniPreLayer"..aniId, aniLayer)
    else
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():addAniToLine(aniId,line,aniLayer,zOrder)
        end
        DoEventHandler.addShowAni({aniId = aniId,line = line})
    end

    local function completeCallback()
        if DoEventHandler._aniPlayDelayAction then
            DoEventHandler._actionNode:stopAction(DoEventHandler._aniPlayDelayAction)
            DoEventHandler._aniPlayDelayAction = nil
        end
        if not nextImmediately then
            DoEventHandler.nextEventsVec(event)
        end
    end
    local play = animation:playAni({name = playAction,playTimes = -1,completeCallback = completeCallback})

    if keepTime > 0 then
        DoEventHandler._aniPlayDelayAction = cc.Sequence:create(cc.DelayTime:create(keepTime),cc.CallFunc:create(function()
            DoEventHandler._aniPlayDelayAction = nil
            animation:stop()
            if not nextImmediately then
                DoEventHandler.nextEventsVec(event)
            end
        end))
        DoEventHandler._actionNode:runAction(DoEventHandler._aniPlayDelayAction)
    end

    if nextImmediately then
        DoEventHandler.nextEventsVec(event)
    end

end

function DoEventHandler.doAniMoveEvent(event)
    local sx = event.mSx + DoEventHandler.Ox
    local sy = (event.mSy == 0) and FieldManager:getCharacterY() or event.mSy
    local ex = event.mEx + DoEventHandler.Ox
    local ey = (event.mEy == 0) and FieldManager:getCharacterY() or event.mEy
    local time = event.mTime
    local endDelayTime = event.mEndDelayTime
    local aniDirectory = event.mAniDirectory
    local armName = event.mArmatureName
    local action = event.mPlayAction
    local scale = event.mScale
    local particleFile = event.mParticleFile
    local zOrder = event.mZOrder
    local animationId = event.mAniId
    local immediately = event.mImmediately

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    local character = DoEventHandler.getCharacter()

    if character then
        local line = character:getLine()
        local aniId = animationId or math.floor(app:getTime() * 1000)
        local Armature = app:getClass("Armature")
        local animation = Armature.create({
            path = aniDirectory,
            armatureName = armName,
            animationName = "",
            skeletonName = armName,
            textureName = armName
        })

        local aniLayer = display.newLayer()
        -- aniLayer:setScale(scale)

        if sx > ex then--面向左
            animation:setScaleX(1 * scale)
        else--面向右
            animation:setScaleX(-1 * scale)
        end
        animation:setScaleY(scale)

        animation:setPosition(cc.p(0,0))
        aniLayer:addChild(animation)

        if particleFile and string.len(particleFile) > 0 then
            local particle = cc.ParticleSystemQuad:create(particleFile)
            particle:setPosition(cc.p(0,0))
            aniLayer:addChild(particle)
        end

        aniLayer:setPosition(cc.p(sx,sy))
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():addAniToLine(aniId,line,aniLayer,zOrder)
        end
        DoEventHandler.addShowAni({aniId = aniId,line = line})

        local sequenceAction = cc.Sequence:create(
            cc.MoveTo:create(time,cc.p(ex,ey)),
            -- cc.DelayTime:create(endDelayTime),
            cc.CallFunc:create(function()
                if cc.isAlive(MapManager:getMap()) then
                    MapManager:getMap():removeAni(aniId)
                end
                if not immediately then
                    DoEventHandler.nextEventsVec(event)
                end
            end))
        aniLayer:runAction(sequenceAction)
        if immediately then
            DoEventHandler.nextEventsVec(event)
        end
    else
        DoEventHandler.nextEventsVec(event)
    end

end

function DoEventHandler.doDeleteAniEvent(event)
    local deleteAniId = event.mDeleteId
    local resumeNpcId = event.mResumeNpcId

    local posNpc = NpcManager:getNpcById(resumeNpcId)
    if posNpc then
        posNpc:setVisible(true)
    end

    if cc.isAlive(MapManager:getMap()) then
        MapManager:getMap():removeAni(deleteAniId)
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.addShowAni(aniTab)
    table.insert(DoEventHandler.ANI_IDS,aniTab)
end

function DoEventHandler.removeAllAni()
    local map = MapManager:getMap()
    if cc.isAlive(map) then
        for i,v in ipairs(DoEventHandler.ANI_IDS) do
            local aniId = v.aniId
            local line = v.line
            map:removeAniByIdAndLine(aniId,line)
        end
    end
    DoEventHandler.ANI_IDS = {}
end

function DoEventHandler.doSoundControlEvent(event)
    local pause = event.mPause
    local fadeTime = event.mFadeTime
    if pause then
        if fadeTime then
            AM.fadeOutAll(fadeTime)
        else
            AM.pauseAll()
        end
    else
        if fadeTime then
            AM.fadeInAll(fadeTime)
        else
            AM.resumeAll()
        end
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.isAudioIdExsit(audioId)
    for i = #DoEventHandler.PLAY_SOUND_IDS,1,-1 do
        local id = DoEventHandler.PLAY_SOUND_IDS[i]
        if id == audioId then
            return true
        end
    end
    return false
end

function DoEventHandler.addAudioId(audioId)
    if not DoEventHandler.isAudioIdExsit(audioId) then
        table.insert(DoEventHandler.PLAY_SOUND_IDS,audioId)
    end
end

function DoEventHandler.removeAudioId(audioId)
    for i = #DoEventHandler.PLAY_SOUND_IDS,1,-1 do
        local id = DoEventHandler.PLAY_SOUND_IDS[i]
        if id == audioId then
            table.remove(DoEventHandler.PLAY_SOUND_IDS,i)
        end
    end
end

function DoEventHandler.stopAllAudio()
    for i = #DoEventHandler.PLAY_SOUND_IDS,1,-1 do
        local id = DoEventHandler.PLAY_SOUND_IDS[i]
        AM.stop(id)
        table.remove(DoEventHandler.PLAY_SOUND_IDS,i)
    end
end

function DoEventHandler.clearAllAudioIds()
    DoEventHandler.PLAY_SOUND_IDS = {}
end

function DoEventHandler.doPlaySoundEvent(event)
    local soundPath = event.mSoundPath
    local loop = event.mLoop
    local key = event.mKey
    local playTime = event.mPlayTime
    local soundId = event.mSoundId
    local delete = event.mDelete

    if delete then
        if key and DoEventHandler.mEventSoundTab[key] then
            local tab = DoEventHandler.mEventSoundTab[key]
            if tab.audioId then
                AM.stop(tab.audioId)
                DoEventHandler.removeAudioId(tab.audioId)
            end
            DoEventHandler.mEventSoundTab[key] = nil
        end
        DoEventHandler.nextEventsVec(event)
        return
    end

    local audioId
    if soundId then
        AM.playSoundById(soundId)
    else
        if soundPath then
            audioId = AM.play(soundPath,loop)
        end
    end

    if playTime then
        if audioId then
            local seqAction = cc.Sequence:create(cc.DelayTime:create(playTime),cc.CallFunc:create(function()
                AM.stop(audioId)
            end))
            DoEventHandler._actionNode:runAction(seqAction)
        end
    else
        DoEventHandler.addAudioId(audioId)
        if not DoEventHandler.mEventSoundTab then
            DoEventHandler.mEventSoundTab = {}
        end
        if key then
            DoEventHandler.mEventSoundTab[key] = {audioId = audioId,soundPath = soundPath}
        end
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doStopSoundEvent(event)
    local key = event.mKey

    if key and DoEventHandler.mEventSoundTab[key] then
        -- local audioId = DoEventHandler.mEventSoundTab[key]
        local tab = DoEventHandler.mEventSoundTab[key]
        -- if tab.audioId and tab.soundPath then
        if tab.audioId then
            -- AudioManager.pause(tab.audioId)
            -- AudioManager.uncache(tab.soundPath)
            AM.stop(tab.audioId)
            DoEventHandler.removeAudioId(tab.audioId)
        end
        DoEventHandler.mEventSoundTab[key] = nil
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.isShowNpcIdExsit(npcId)
    for i = #DoEventHandler.SHOW_NPC_IDS,1,-1 do
        local id = DoEventHandler.SHOW_NPC_IDS[i]
        if id == npcId then
            return true
        end
    end
    return false
end

function DoEventHandler.addShowNpcId(npcId)
    if not DoEventHandler.isShowNpcIdExsit(npcId) then
        table.insert(DoEventHandler.SHOW_NPC_IDS,npcId)
    end
end

function DoEventHandler.removeShowNpcId(npcId)
    for i = #DoEventHandler.SHOW_NPC_IDS,1,-1 do
        local id = DoEventHandler.SHOW_NPC_IDS[i]
        if id == npcId then
            table.remove(DoEventHandler.SHOW_NPC_IDS,i)
        end
    end
end

function DoEventHandler.removeAllShowNpc()
    for i = #DoEventHandler.SHOW_NPC_IDS,1,-1 do
        local npcId = DoEventHandler.SHOW_NPC_IDS[i]
        local npc = NpcManager:getNpcById(npcId)
        if npc then
            table.remove(DoEventHandler.SHOW_NPC_IDS,i)
            local line = npc:getLine()
            NpcManager:deleteNpcById(npcId,line)
        end
    end
    DoEventHandler.SHOW_NPC_IDS = {}
end

function DoEventHandler.isOriginalNpcIdExist(npcId)
    for i = #DoEventHandler.ORIGINAL_NPC_VISIBLE, 1, -1 do
        local data = DoEventHandler.ORIGINAL_NPC_VISIBLE[i]
        if data.npcId == npcId then
            return true
        end
    end
    return false
end

function DoEventHandler.addOriginalNpcVisible(npcId, visible)
    if DoEventHandler.isOriginalNpcIdExist() then return end

    table.insert(DoEventHandler.ORIGINAL_NPC_VISIBLE, {npcId = npcId, visible = visible})
end

function DoEventHandler.revertAllNpcVisible()
    for i = #DoEventHandler.ORIGINAL_NPC_VISIBLE, 1, -1 do 
        local data = DoEventHandler.ORIGINAL_NPC_VISIBLE[i]
        local npc = NpcManager:getNpcById(data.npcId)
        if npc then
            npc:setVisibleInEvent(data.visible)
            npc:setEventVisibility(false)
        end
    end
    DoEventHandler.ORIGINAL_NPC_VISIBLE = {}
end

function DoEventHandler.doShowNpcEvent(event)
    local npcId = event.mNpcId
    local enter = event.mEnter

    if enter == 2 then
        local npc = NpcManager:getNpcById(npcId)

        if npc then
            DoEventHandler.removeShowNpcId(npcId)
            NpcManager:deleteNpcById(npcId,npc:getLine())
        end

        DoEventHandler.nextEventsVec(event)

        return
    end

    local x = event.mX + DoEventHandler.Ox
    local y = (event.mY == 0) and FieldManager:getCharacterY() or event.mY
    local visible = event.mVisible

    local targetDir = event.mTargetDir
    local showType = event.mShowType

    if npcId <= 0 then
        local mainCharacter = DoEventHandler.getCharacter()

        local sx = x or mainCharacter:getPositionX()
        mainCharacter:showLocationX(sx)

        if targetDir == mainCharacter.DIR_LEFT then
            mainCharacter:faceToDirectionNotPlayAction("left")
        elseif targetDir == mainCharacter.DIR_RIGHT then
            mainCharacter:faceToDirectionNotPlayAction("right")
        end
    else
        local npc = NpcManager:getNpcById(npcId)
        if not npc then
            local npcConfig = GD:queryMapNpc(npcId)
            local npcUid = NpcManager:generateNpcUid()
            npc = NpcFactory:createNpc(npcConfig, npcUid)
            if npc then
                DoEventHandler.addShowNpcId(npcId)
            end
        end

        if npc then
            -- 存储npc初始显示状态
            DoEventHandler.addOriginalNpcVisible(npcId, npc:isVisible())

            if visible then  
                npc:setVisibleInEvent(true)
            else
                npc:setVisibleInEvent(false)
            end

            npc:stopRayCast(true)
            npc:showLocation(cc.p(x,y))
            npc:setDirection(targetDir)
            npc:forceDirection()
        end
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.focusTrans(npcId,time,callback,event)
    local function overCall()
        if callback then
            callback()
        end
    end
    if npcId <= 0 then
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():setFocusNpc(nil)
            MapManager:setFocusCharacter({character = DoEventHandler.getCharacter()})
            MapManager:backNpcFocusToOldCharacter({time = time,callback = overCall})
        else
            overCall()
        end
    else
        local npc = NpcManager:getNpcById(npcId)
        if npc then
            if cc.isAlive(MapManager:getMap()) then
                MapManager:getMap():transitionFocusToNpc(npc,time,callback)
            else
                overCall()
            end
        else
            overCall()
        end
    end
end

function DoEventHandler.doFocusTransEvent(event)
    local npcId = event.mNpcId
    local time = event.mTime or 0

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    DoEventHandler.focusTrans(npcId,time,function()
        DoEventHandler.nextEventsVec(event)
    end,event)

end

function DoEventHandler.doNpcJumpEvent(event)
    local npcId = event.mNpcId
    local time = event.mTime
    local x = event.mX
    local y = event.mY
    local jumpHeight = event.mJumpHeight
    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end
    local function call()
        DoEventHandler.nextEventsVec(event)
    end

    local npc = NpcManager:getNpcById(npcId)
    if npc then
        local action = cc.Sequence:create(cc.JumpTo:create(time,cc.p(x,y),jumpHeight,1),cc.CallFunc:create(call))
        npc:excuteAction(action)
    else
        call()
    end
end

function DoEventHandler.doCameraMoveEvent(event)
    local offsetX = event.mOffsetX
    local time = event.mTime
    local delayTime = event.mDelayTime
    local pauseAutoCamera = event.mPauseAutoCamera

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    MapManager:pauseEventAutoAdjustCamera(true)
    local function excute()
        local cameraX = MapManager:getCameraX()
        local destCameraX = cameraX + offsetX
        local destCameraY = MapManager:getCameraY()
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():eventParallaxNodesMoveTo(cc.p(0 - destCameraX,0 - destCameraY),time,function()
                MapManager:setCameraX(destCameraX)
                DoEventHandler.nextEventsVec(event)
            end)
        end
    end

    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(delayTime),
                cc.CallFunc:create(excute)))
    else
        excute()
    end


end

function DoEventHandler.doRelativeCameraMoveEvent(event)
    local npcId = event.mNpcId
    local relativeSpace = event.mRelativeSpace
    local time = event.mTime
    local pauseAutoCamera = event.mPauseAutoCamera

    if pauseAutoCamera then
        MapManager:pauseEventAutoAdjustCamera(true)
    else
        MapManager:pauseEventAutoAdjustCamera(false)
    end

    local destCameraX = 0
    local destCameraY = MapManager:getCameraY()
    if npcId == 0 then
        local character = DoEventHandler.getCharacter()
        local px = character:getPositionX()
        destCameraX = px - (display.width / 2) + relativeSpace
    else
        local npc = NpcManager:getNpcById(npcId)
        if npc then
            local px = npc:getPositionX()
            destCameraX = px - (display.width / 2) + relativeSpace
        end
    end

    if cc.isAlive(MapManager:getMap()) then
        MapManager:getMap():eventParallaxNodesMoveTo(cc.p(0 - destCameraX,0 - destCameraY),time,function()
            MapManager:setCameraX(destCameraX)
            DoEventHandler.nextEventsVec(event)
        end)
    end
end

function DoEventHandler.doWaitEvent(event)
    local waitTime = event.mTime

    if DoEventHandler.isSkipEvents() then
        waitTime = waitTime / DoEventHandler.SKIP_FACTOR
    end

    local action = cc.Sequence:create(cc.DelayTime:create(waitTime),cc.CallFunc:create(function()
        DoEventHandler.nextEventsVec(event)
    end))
    DoEventHandler._actionNode:runAction(action)
end

function DoEventHandler.doNpcDirectionEvent(event)
    local npcId = event.mNpcId
    local direction = event.mDirection

    if npcId <= 0 then
        local mainCharacter = DoEventHandler.getCharacter()

        if direction == "l" then
            mainCharacter:faceToDirectionNotPlayAction("left")
        elseif direction == "r" then
            mainCharacter:faceToDirectionNotPlayAction("right")
        end
    else
        local npc = NpcManager:getNpcById(npcId)
        if npc then

            if direction == "l" then
                npc:setDirection(npc.DIR_LEFT)--left
            elseif direction == "r" then
                npc:setDirection(npc.DIR_RIGHT)--right
            end
            npc:forceDirection()
        end
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doCameraZoomEvent(event)
    local focusId = event.mFocusId
    local scale = event.mScale
    local time = event.mTime
    local useTime = event.mUseTime
    local delayTime = event.mDelayTime
    local cameraFollow = event.mCameraFollow

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    local focusTime = time
    local function excute()
        DoEventHandler.focusTrans(focusId,focusTime,function()
            if not cameraFollow then
                MapManager:setFocusCharacter({character = nil})
            end
        end,event)
        -- 先暂存之前的scale，设置完新的scale的时候，再把旧的sacle置回到内存中
        local preScale = app:getValue("UserMapScale", 1)
        MapManager:forceCameraZoomToDest({time = time,dstScale = scale, call = function()
            DoEventHandler.nextEventsVec(event)
            app:saveValue("UserMapScale", preScale)
        end})
        
    end

    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(cc.Sequence:create(cc.DelayTime:create(delayTime),cc.CallFunc:create(function()
            excute()
        end)))
    else
        excute()
    end
end

function DoEventHandler.doCameraZoomToEvent(event)
    local focusId = event.mFocusId
    local scale = event.mScale
    local time = event.mTime
    local scx = event.mScx
    local scy = event.mScy
    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    DoEventHandler.doCameraZoomEvent(event)
    do return end

    if DoEventHandler.mEventCameraMoveX then

        local function actionOver()

        end
        MapManager:getMap():cameraZoomTo({
            time = 0,
            mx = 0 - DoEventHandler.mEventCameraMoveX,
            my = 0 - DoEventHandler.mEventCameraMoveY,
            scale = 1,
            callback = actionOver})
    end

    local focusRole = NpcManager:getNpcById(focusId)

    if focusRole then
        local function callback()

        end
        MapManager:getMap():setFocusNpcForInit(focusRole)
    else
        local character = DoEventHandler.getCharacter()

        focusRole = character
    end

    if not focusRole then
        return
    end

    local inScreenX = display.width / 2
    local inScreenY = focusRole:getPositionY()

    local scaleInScreenX = inScreenX * scale
    local destX = scx
    DoEventHandler.mEventCameraMoveX = (destX - scaleInScreenX)

    local scaleInScreenY = inScreenY * scale
    local destY = display.width / 6 - MapManager:getMap():getMapOffsetY()
    DoEventHandler.mEventCameraMoveY = (destY - scaleInScreenY)

    local function actionOver()
        DoEventHandler.nextEventsVec(event)
    end

    local function forceZoomOver()

    end

    MapManager:forceCameraZoomIn({time = 0.5,callback = forceZoomOver})


    MapManager:getMap():cameraZoomTo({
        time = time,
        mx = DoEventHandler.mEventCameraMoveX,
        my = DoEventHandler.mEventCameraMoveY,
        scale = scale,
        callback = actionOver})
end

function DoEventHandler.doNpcMoveEvent(event)
    local npcId = event.mNpcId
    local dx = event.mDx + DoEventHandler.Ox
    local speed = event.mSpeed
    local action = event.mAction
    local lostFocusDistance = event.mLostFocusDistance
    if DoEventHandler.isSkipEvents() then
        speed = speed * DoEventHandler.SKIP_FACTOR
    end


    local function lostFocus()
        MapManager:setFocusCharacter({character = nil})
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():setFocusNpc(nil)
        end
    end

    if npcId <= 0 then
        local character = DoEventHandler.getCharacter()
        if cc.isAlive(character) then
            local function callback()
                MapManager:pauseRunCameraZoomForEvent(false)
                character:setRunAction(nil)
                DoEventHandler.nextEventsVec(event)
            end

            MapManager:pauseRunCameraZoomForEvent(true)

            character:setRunAction(action)
            character:setEventTargetX(dx,speed,callback,lostFocusDistance,lostFocus)
        end
    else
        local function callback()
            DoEventHandler.nextEventsVec(event)
        end
        local npc = NpcManager:getNpcById(npcId)
        if cc.isAlive(npc) then
            local scale = 1
            if cc.isAlive(MapManager:getMap()) then
                scale = MapManager:getMap():getScale()
            end
            npc:setSpeed(speed * scale)
            npc:setEventTargetX(dx,callback,lostFocusDistance,lostFocus)
            npc:playEventAction(action,nil,0,true)
        else
            callback()
        end
    end
end

function DoEventHandler.doRandomEvent(event)
    local eventsVec = event:getRandomEvents()
    if eventsVec then

        local syncEventsVec = Vector.new()
        local loopRandomEventEvent = LoopRandomEventEvent.new({event = "LOOP_RANDOM_EVENT_EVENT",loopEvent = event})
        syncEventsVec:add(loopRandomEventEvent)
        eventsVec:add(syncEventsVec)

        DoEventHandler.startEvents(eventsVec)
    else
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doLoopRandomEventEvent(event)
    if DoEventHandler.isTouchForNextTalk() then
        local loopEvent = event.mLoopEvent
        local eventsVec = loopEvent:getRandomEvents()
        if eventsVec then

            local syncEventsVec = Vector.new()
            local loopRandomEventEvent = LoopRandomEventEvent.new({event = "LOOP_RANDOM_EVENT_EVENT",loopEvent = loopEvent})
            syncEventsVec:add(loopRandomEventEvent)
            eventsVec:add(syncEventsVec)

            DoEventHandler.startEvents(eventsVec)
        end
    else
        DoEventHandler.nextEventsVec(event)
    end

end

function DoEventHandler.doPlayActionEvent(event)
    local npcId = event.mNpcId
    local action = event.mAction
    local armName = event.mArmName
    local immediately = event.mNextImmediately
    local delayTime = event.mDelayTime
    local playTimes = event.mPlayTimes
    local showDelayTime = event.mShowDelayTime
    local overKeep = event.mOverKeep
    if DoEventHandler.isSkipEvents() then
        immediately = true
    end

    local function call()
        if not immediately then
            DoEventHandler.nextEventsVec(event)
        end
    end

    local function excuteMethod()
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(0.05),
                cc.CallFunc:create(function()
                    if npcId == 0 then
                        local character = DoEventHandler.getCharacter()
                        if cc.isAlive(character) then
                            character:playEventsAction(action,call,delayTime,false,playTimes,nil,nil,overKeep)
                        end
                    else
                        local npc = NpcManager:getNpcById(npcId)
                        if npc then
                            npc:playEventAction(action,call,delayTime,false,playTimes,overKeep)
                        else
                            call()
                        end
                    end
                end)))
    end

    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(delayTime),
                cc.CallFunc:create(excuteMethod)))
    else
        excuteMethod()
    end

    if immediately then
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doDeleteNpcEvent(event)
    local npcId = event.mNpcId

    local npc = NpcManager:getNpcById(npcId)

    if npc then
        DoEventHandler.removeShowNpcId(npcId)
        local line = npc:getLine()
        NpcManager:deleteNpcById(npcId,line)
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doNpcVisibilityEvent(event)
    local npcId = event.mNpcId
    local visible = event.mVisible
    local delayTime = event.mDelayTime
    local showType = event.mShowType
    local fadeTime = event.mFadeTime

    if DoEventHandler.isSkipEvents() then
        delayTime = delayTime / DoEventHandler.SKIP_FACTOR
    end

    if npcId <= 0 then
        local character = DoEventHandler.getCharacter()

        local function excuteMethod()
          if visible then
                character:setVisibleInEvent(true)
            else
                character:setVisibleInEvent(false)
            end
        end
        if delayTime > 0 then
            local sequenceAction = cc.Sequence:create(cc.DelayTime:create(delayTime),cc.CallFunc:create(function()
                excuteMethod()
            end))
            character:runAction(sequenceAction)
        else
            excuteMethod()
        end

        --FieldManager:getMyCharacter():setVisible(visible)

    else
        local npc = NpcManager:getNpcById(npcId)
        if npc then
            local function excuteMethod()
                -- 存储npc初始显示状态
                DoEventHandler.addOriginalNpcVisible(npcId, npc:isVisible())

                if visible then
                    npc:setVisibleInEvent(true)
                    npc:setOpacity(0)
                    npc:runAction(cc.FadeIn:create(fadeTime))
                else
                    npc:runAction(cc.Sequence:create(cc.FadeOut:create(fadeTime),cc.CallFunc:create(function()
                        npc:setVisibleInEvent(false)
                    end)))
                end

                --fadeTime
            end

            if delayTime > 0 then
                local sequenceAction = cc.Sequence:create(cc.DelayTime:create(delayTime),cc.CallFunc:create(function()
                    excuteMethod()
                end))
                npc:excuteAction(sequenceAction)
            else
                excuteMethod()
            end
            --npc:setVisible(visible)

        end
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doCameraBackToOrigin(event)
    local time = event.mTime
    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    MapManager:forceCameraZoomIn({time = time,callback = function()end})

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doMonsterCallEvent(event)
end

function DoEventHandler.doExclamMarkEvent(event)
    local npcId = event.mNpcId
    local immediately = event.mImmediately
    local dir = event.mDir
    local armName = event.mArmName
    local action = event.mAction

    local delayTime = event.mDelayTime
    local sound = event.mSound
    local playTimes = event.mPlayTimes

    if DoEventHandler.isSkipEvents() then
        immediately = true
    end

    local function call()
        if not immediately then
            DoEventHandler.nextEventsVec(event)
        end
    end

    local function excute()
        if sound then
            AM.playSoundById(sound)
        end

        local params = {dir = dir,name = armName,action = action,times = playTimes}

        if npcId <= 0 then
            local character = DoEventHandler.getCharacter()

            character:showExclamMark(call,params)
        else
            local npc = NpcManager:getNpcById(npcId)
            if npc then
                npc:showExclamMark(call,params)
            else
                call()
            end
        end
    end


    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(delayTime),
                cc.CallFunc:create(excute)))
    else
        excute()
    end

    if immediately then
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doTaskMarkVisibilityEvent(event)
    local npcId = event.mNpcId
    local visible = event.mVisible

    local npc = NpcManager:getNpcById(npcId)
    if npc then
        --npc:mainTaskMarkVisibility(visible)
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doNpcFadeEvent(event)
    local npcId = event.mNpcId
    local opacity = event.mOpacity
    local time = event.mTime
    local immediately = event.mImmediately
    local delayTime = event.mDelayTime
    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    local function callOver()
        if not immediately then
            DoEventHandler.nextEventsVec(event)
        end

    end

    local action = cc.Sequence:create(cc.DelayTime:create(delayTime),cc.FadeTo:create(time,opacity),cc.CallFunc:create(callOver))
    if npcId <= 0 then
        local character = DoEventHandler.getCharacter()

        character:runAction(action)
    else
        local npc = NpcManager:getNpcById(npcId)
        if npc then
            npc:excuteAction(action)
        else
            callOver()
        end
    end

    if immediately then
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doSignMarkEvent(event) 
    local npcId = event.mNpcId
    local mark = event.mMark
    local show = event.mShow

    local npc = NpcManager:getNpcById(npcId)
    if npc then
        if mark ~= nil then
            npc:setMark(mark)
            npc:createMark(mark)
        end
    end
    if show ~= nil then
        local npc = NpcManager:getNpcById(npcId)
        if npc then
            if show then
                npc:setDoingEvents(false)
                npc:currentMarkVisibility(true)
            else
                npc:setDoingEvents(true)
                npc:currentMarkVisibility(false)
            end
        end
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doTaskGatherEvent(event)
    local gatherNpcId = event.npcId
    local npcUid = event.npcUid

    DoEventHandler.DoTaskGather = true
    DoEventHandler.setDoGatherAction(true)
    NpcManager:hideAllNpcMark()
    NpcManager:stopAllNpcMarkForEvent(true)
    app:dispatchCustomEvent("EVENT_TASK_GUIDE_VISIBILITY",{visible = false})

    local gatherNpc = NpcManager:getNpcByUid(npcUid)
    if gatherNpc then
        local action = "pick"
        local function gather()
            if gatherNpc and gatherNpc:getTaskId() then
                -- TaskManager:C2S_TaskGatherRequest(gatherNpc:getTaskId(),gatherNpcId,function()
                --     gatherNpc = NpcManager:getNpcByUid(npcUid)
                --     if gatherNpc then
                --         gatherNpc:setTaskGathered(true)
                --         gatherNpc:setVisible(false)
                --         NpcManager:deleteNpcByUid(npcUid)
                --     end
                --     DoEventHandler.gatherOver(event)
                -- end)
                TaskManager:C2S_TaskGatherRequest(gatherNpc:getTaskId(),gatherNpcId)
                -- 以上代码会造成 已经在执行任务剧情的脚本了，然后又回调到这里了
                gatherNpc = NpcManager:getNpcByUid(npcUid)
                if gatherNpc then
                    gatherNpc:setTaskGathered(true)
                    gatherNpc:setVisible(false)
                    NpcManager:deleteNpcByUid(npcUid)
                end
                DoEventHandler.gatherOver(event)

            end
        end

        local function playOpenAction(callback)
            if gatherNpc and (not DoEventHandler.isStopGatherAction()) then
                local duration = DoEventHandler.getCharacter():playEventsAction(action,nil,0,false)
                local openAction = cc.Sequence:create(cc.DelayTime:create(duration),cc.CallFunc:create(callback))
                DoEventHandler._actionNode:runAction(openAction)
                DoEventHandler.addGatherAction(openAction)

                gatherNpc:stopMarkForEvent(true)

                UIHandler:showGatherControl()
                UIHandler:setGatherControlTime(duration)
                UIHandler:setGatherControlProgress(0,1)
            else
                DoEventHandler.gatherOver(event)
            end
        end

        playOpenAction(gather)
    else
        DoEventHandler.gatherOver(event)
    end
end

function DoEventHandler.doGatherConditionalEvent(event)
    local gatherNpcId = event.mNpcId
    local todo = event.mTodo

    local isCanGather = DoEventHandler.isCanGather(gatherNpcId,todo)
    if not isCanGather then
        local gatherNpc = NpcManager:getNpcIfUidNotNil(gatherNpcId)
        if gatherNpc then
            gatherNpc:setDoingEvents(false)
        end
        DoEventHandler.setCurrrentMark(nil)
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.clearGatherStatus()
    UIHandler:hideGatherControl()
    DoEventHandler.setDoGatherAction(false)
    DoEventHandler.setCurrrentMark(nil)
    DoEventHandler.DoTaskGather = false
end

function DoEventHandler.gatherOver(event,gatherNpcId)
    local character = DoEventHandler.getCharacter()
    if cc.isAlive(character) then
        character:stopAllActions()
        character:overEventActionPlaying()
        character:forceStandby()
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():setFocusCharacterNotInit(character)
        end
    end

    UIHandler:hideGatherControl()
    NpcManager:stopAllNpcMarkForEvent(false)
    NpcManager:showAllNpcMark()

    DoEventHandler.foreCurrentEventsOver()
    DoEventHandler.setDoGatherAction(false)
    DoEventHandler.setCurrrentMark(nil)
    local npcId, npcUid
    if gatherNpcId then
        npcId = gatherNpcId
    elseif event and event.npcId then
        npcId = event.npcId
    end

    if event then
        npcUid = event.npcUid
    end

    local gatherNpc = NpcManager:getNpcByUid(npcUid)
    if not gatherNpc then
        gatherNpc = NpcManager:getNpcById(npcId)
    end
    if gatherNpc then
        gatherNpc:stopEventAction()
        gatherNpc:setDoingEvents(false)
    end

    DoEventHandler.DoTaskGather = false
    DoEventHandler.stopGlobalGatherAction()
    app:dispatchCustomEvent("EVENT_TASK_GUIDE_VISIBILITY",{visible = true})

    DoEventHandler.stopAllGatherAction()
end

function DoEventHandler.stopGlobalGatherAction()
    if DoEventHandler.m_GatherAction then
        DoEventHandler._actionNode:stopAction(DoEventHandler.m_GatherAction)
        DoEventHandler.m_GatherAction = nil
    end
end

function DoEventHandler.setStopGatherAction(stop,gatherNpcId)
    DoEventHandler.mStopGatherAction = stop
    if stop then
        DoEventHandler.gatherOver(nil,gatherNpcId)
    end
end

function DoEventHandler.isStopGatherAction()
    return DoEventHandler.mStopGatherAction
end

function DoEventHandler.setDoGatherAction(isDo)
    DoEventHandler.mDoGatherAction = isDo
end

function DoEventHandler.isDoGatherAction()
    return DoEventHandler.mDoGatherAction
end

function DoEventHandler.isCanGather(gatherNpcId,todo)
    local oreConfig = GD:queryOreConfigById(gatherNpcId)
    if not oreConfig then
        return false
    end

    local costPower = tonumber(oreConfig.power)
    local curPower = UD:getPower()
    if curPower < costPower then
        app:popMessage("powernotenough")
        return false
    end

    local canGather = false

    local needItems = string.split(oreConfig.item,";")
    for i,v in ipairs(needItems) do
        local itemId = v
        local isToolExsit = true
        if isToolExsit then
            canGather = true
            break
        end
    end
    if todo == "chests" then
        canGather = true
    end

    if not canGather then
        if todo == "dig" then
            app:popMessage("nohoe")
        elseif todo == "fishing" then
            app:popMessage("nofishingrob")
        elseif todo == "herb" then
            app:popMessage("nogloves")
        end
        return false
    end

    return true
end

function DoEventHandler.setCurrrentMark(mark)
    DoEventHandler.mCurrrentMark = mark
end

function DoEventHandler.getCurrrentMark()
    return DoEventHandler.mCurrrentMark
end

function DoEventHandler.isGather()
    local mark = DoEventHandler.getCurrrentMark()
    if mark == "mining"
        or mark == "fishing"
        or mark == "herb"
        or mark == "identify"
        or mark == "wreck"
        or mark == "chests"
        or mark == "grabfish"
    then
        return true
    end
    if DoEventHandler.isDoGatherAction() then
        return true
    end
    if DoEventHandler.DoTaskGather then
        return true
    end
    return false
end

function DoEventHandler.moveOperateAtGather()
    if DoEventHandler.isDoGatherAction() then
        DoEventHandler.setStopGatherAction(true)
    end
end

function DoEventHandler.doDelayAction(delayTime,callback)
    DoEventHandler.stopDelayAction()
    if not DoEventHandler._eventDelayAction then
        DoEventHandler._eventStopGather = false
        DoEventHandler._eventDelayAction = cc.Sequence:create(cc.DelayTime:create(delayTime),cc.CallFunc:create(function()
            DoEventHandler._eventStopGather = true
            DoEventHandler._eventDelayAction = nil
            if callback then
                callback()
            end
        end))
        DoEventHandler._actionNode:runAction(DoEventHandler._eventDelayAction)
    end
end

function DoEventHandler.stopDelayAction()
    if DoEventHandler._eventDelayAction then
        DoEventHandler._actionNode:stopAction(DoEventHandler._eventDelayAction)
        DoEventHandler._eventDelayAction = nil
    end
end

function DoEventHandler.clearEventStopGather()
    DoEventHandler._eventStopGather = nil
end

function DoEventHandler.isEventStopGather()
    return DoEventHandler._eventStopGather
end

function DoEventHandler.addGatherAction(action)
    if not DoEventHandler._gatherActions then
        DoEventHandler._gatherActions = {}
    end
    table.insert(DoEventHandler._gatherActions,action)
end

function DoEventHandler.stopAllGatherAction()
    if not DoEventHandler._gatherActions then return end
    for i,action in ipairs(DoEventHandler._gatherActions) do
        if not tolua.isnull(action) then
            DoEventHandler._actionNode:stopAction(action)
        end
    end
    DoEventHandler._gatherActions = {}
end

function DoEventHandler.doGatherActionEvent(event)
    local function isGatherNpcOver(gatherNpc)
        if cc.isDead(gatherNpc) then
            DoEventHandler.gatherOver(event)
            return true
        end
        return false
    end

    FieldManager:refreshMyCharacterPositionToServer()
    DoEventHandler.setDoGatherAction(true)
    DoEventHandler.clearEventStopGather()
    DoEventHandler.stopDelayAction()

    NpcManager:hideAllNpcMark()
    NpcManager:stopAllNpcMarkForEvent(true)
    app:dispatchCustomEvent("EVENT_TASK_GUIDE_VISIBILITY",{visible = false})

    local todo = event.mTodo
    local gatherNpcId = event.npcId
    local npcUid = event.npcUid

    DoEventHandler.setStopGatherAction(false)

    local gatherNpc = NpcManager:getNpcByUid(npcUid)
    local pickPointData = UD:getGatherDataByNpcId(gatherNpcId)
    -- dump(pickPointData)
    -- dump(gatherNpc)
    -- print(npcUid)
    -- print(todo)

    if todo == "dig" or todo == "fishing" or todo == "herb" or todo == "chests" or todo == "identify" or todo == "wreck" or todo == "grabfish" then
        local function isCanGather(todo)
            return DoEventHandler.isCanGather(gatherNpcId,todo)
        end

        if not isCanGather(todo) or not pickPointData then
            DoEventHandler.gatherOver(event)
            return
        end

        if todo == "dig" or todo == "herb" or todo == "identify" or todo == "wreck" or todo == "grabfish" then
            local action = "dig_loop"
            if todo == "herb" or todo == "identify" or todo == "wreck" or todo == "grabfish" then
                action = "pick"
            end
            if not cc.isDead(gatherNpc) then
                if gatherNpc:isOre() or gatherNpc:isHerb() or gatherNpc:isIdentify() or gatherNpc.isWreck() then -- or gatherNpc:isChests()

                    local function prepareOk()
                        local denominator = pickPointData.num
                        local actionTime = 1.2
                        local gatherCount = 2
                        if  todo == "dig"then
                            gatherCount = 2
                            actionTime = 1.16
                        elseif todo == "herb" or todo == "identify" or todo == "wreck" or todo == "grabfish" then
                            gatherCount = 1
                            actionTime = 2.92
                        end     
                        local actionCount = 0
                        local totalActionCount = 0
                        local maxCount = gatherCount * denominator
                        -- print("maxCount = " .. maxCount)

                        local function doGather()
                            if not cc.isDead(gatherNpc) and isCanGather(todo) and (not DoEventHandler.isStopGatherAction()) then
                                if gatherNpc:isOre() or gatherNpc:isHerb() then-- or gatherNpc:isHerb() or gatherNpc:isChests()
    
                                    local function callback(msg)
                                        if DoEventHandler.isEventStopGather() then return end
                                        DoEventHandler.stopDelayAction()

                                        local currentNum = denominator - msg.num
                                        UIHandler:setGatherControlProgress(currentNum, denominator)

                                        DoEventHandler.gatherOver(event)

                                        -- 采集完了，删除该npc
                                        if msg.num <= 0 then
                                            -- NpcManager:removePickPoint(gatherNpcId)
                                            NpcManager:removePickPointByNpcId(gatherNpcId)
                                        end
                                    end
    
                                    print("pb_pick.C2S_pick, gatherNpcId =", gatherNpcId)
                                    app.session:request("pb_pick.C2S_Pick", { id = gatherNpcId }, callback, nil, function()
                                        if DoEventHandler.isEventStopGather() then
                                            return
                                        end
                                        DoEventHandler.stopDelayAction()

                                        if isGatherNpcOver(gatherNpc) then
                                            return
                                        end
                                        DoEventHandler.gatherOver(event)
                                    end)
                                    DoEventHandler.doDelayAction(5, function()
                                        DoEventHandler.gatherOver(event)
                                    end)
                                end
                            else
                                DoEventHandler.gatherOver(event)
                            end
                        end
    
                        local function playGatherAction()
                            local function gatherActionOvercallback()
                                if not cc.isDead(gatherNpc) and isCanGather(todo) and (not DoEventHandler.isStopGatherAction()) then
                                else
                                    DoEventHandler.gatherOver(event)
                                    return
                                end
    
                                actionCount = actionCount + 1
                                totalActionCount = totalActionCount + 1
    
                                local function nextAction()
                                    local action1 = cc.Sequence:create(cc.CallFunc:create(playGatherAction))
                                    DoEventHandler._actionNode:runAction(action1)
                                    DoEventHandler.addGatherAction(action1)
                                end
    
                                if actionCount == gatherCount then
                                    actionCount = 0
                                    doGather()
                                end

                                if totalActionCount < maxCount then
                                    nextAction()
                                end
                            end
    
                            if not cc.isDead(gatherNpc) and isCanGather(todo) and (not DoEventHandler.isStopGatherAction()) then
                                if not DoEventHandler.getCharacter() then
                                    DoEventHandler.gatherOver(event)
                                    return
                                end
                                local duration = 0
                                local function startPlayAction()
                                    if actionCount % gatherCount == 0 then
                                        local gatherTime = gatherCount * actionTime
                                        UIHandler:setGatherControlTime(gatherTime)
                                    end
                                end
    
                                duration = DoEventHandler.getCharacter():playEventsAction(action,nil,0,false,nil,actionTime,startPlayAction)
    
                                local action = cc.Sequence:create(cc.DelayTime:create(actionTime),cc.CallFunc:create(gatherActionOvercallback))
                                DoEventHandler._actionNode:runAction(action)
                                DoEventHandler.addGatherAction(action)
    
                                if todo == "herb" then
                                    AM.playSoundById(9222)
                                end
                            else--结束
                                DoEventHandler.gatherOver(event)
                            end
                        end
    
                        UIHandler:showGatherControl()

                        playGatherAction()

                        UIHandler:setGatherControlProgress(0, denominator)
                    end

                    prepareOk()
                    -- DoEventHandler.doDelayAction(8, function()
                    --     DoEventHandler.gatherOver(event)
                    -- end)
                else
                    DoEventHandler.gatherOver(event)
                end
            else
                DoEventHandler.gatherOver(event)
            end
        elseif todo == "fishing" then
            if not cc.isDead(gatherNpc) then
                if gatherNpc:isFishPoint() then

                    local function prepareOk()

                        local denominator = pickPointData.num

                        local function playGatherAction()
                            if isGatherNpcOver(gatherNpc) then
                                return
                            end
                            gatherNpc:setGathering(true)
                            local startAction = "fishing"--甩杆
                            local function callback_fishing()
                                if not DoEventHandler.getCharacter() then
                                    DoEventHandler.gatherOver(event)
                                    return
                                end
                                local lowTime = tonumber(S("fishingtimelow"))
                                local topTime = tonumber(S("fishingtimetop"))
                                local fishTime = lowTime / 1000.0--math.random(lowTime,topTime) / 1000.0

                                local function fishOver()
                                    if not DoEventHandler.getCharacter() then
                                        DoEventHandler.gatherOver(event)
                                        return
                                    end
                                    local function fishHookOver()
                                        if not cc.isDead(gatherNpc) and gatherNpc:isGathering() and isCanGather(todo) and (not DoEventHandler.isStopGatherAction()) then
                                            if gatherNpc:isFishPoint() then
                                                local function callback(msg)
                                                    dump(msg.num)
                                                    if DoEventHandler.isEventStopGather() then
                                                        return
                                                    end
                                                    DoEventHandler.stopDelayAction()

                                                    if isGatherNpcOver(gatherNpc) then
                                                        return
                                                    end

                                                    local num = msg.num
                                                    local currentNum = denominator - num
                                                    UIHandler:setGatherControlProgress(currentNum, denominator)

                                                    if currentNum < denominator and gatherNpc:isGathering() then
                                                        local actionNext = cc.Sequence:create(cc.CallFunc:create(playGatherAction))
                                                        DoEventHandler._actionNode:runAction(actionNext)
                                                        DoEventHandler.addGatherAction(actionNext)
                                                    else
                                                        DoEventHandler.gatherOver(event)
                                                    end

                                                    -- 采集完了，删除该npc
                                                    if msg.num <= 0 then
                                                        -- NpcManager:removePickPoint(gatherNpcId)
                                                        NpcManager:removePickPointByNpcId(gatherNpcId)
                                                    end
                                                end

                                                print("pb_pick.C2S_pick, gatherNpcId =",gatherNpcId)
                                                app.session:request("pb_pick.C2S_Pick", { id = gatherNpcId }, callback, nil, function()
                                                    if DoEventHandler.isEventStopGather() then
                                                        return
                                                    end
                                                    DoEventHandler.stopDelayAction()

                                                    if isGatherNpcOver(gatherNpc) then
                                                        return
                                                    end
                                                    DoEventHandler.gatherOver(event)
                                                end)
                                                DoEventHandler.doDelayAction(5, function()
                                                    DoEventHandler.gatherOver(event)
                                                end)
                                            end

                                        else
                                            DoEventHandler.gatherOver(event)
                                        end
                                    end

                                    local actionTime = 1.7
                                    DoEventHandler.getCharacter():overEventActionPlaying()
                                    DoEventHandler.getCharacter():playEventsAction("fish_hook",nil,0,false,nil,actionTime)
                                    local action = cc.Sequence:create(cc.DelayTime:create(actionTime),cc.CallFunc:create(fishHookOver))
                                    DoEventHandler._actionNode:runAction(action)
                                    DoEventHandler.addGatherAction(action)
                                end

                                local actionFishing = cc.Sequence:create(cc.DelayTime:create(fishTime),cc.CallFunc:create(fishOver))
                                DoEventHandler._actionNode:runAction(actionFishing)
                                DoEventHandler.addGatherAction(actionFishing)
                                local fishLoopAction = "fish_wait"
                                DoEventHandler.getCharacter():playEventsAction(fishLoopAction,callback_fishloop,0,true)
                                UIHandler:setGatherControlTime(fishTime)
                            end

                            -- if gatherNpc and storageItem and tonumber(storageItem.amount) >= tonumber(selItemCostNum) and (not DoEventHandler.isStopGatherAction()) then
                            if not cc.isDead(gatherNpc) and gatherNpc:isGathering() and isCanGather(todo) and (not DoEventHandler.isStopGatherAction()) then
                                local actionTime = 1.1
                                DoEventHandler.getCharacter():playEventsAction(startAction,nil,0,false,nil,actionTime)
                                local action = cc.Sequence:create(cc.DelayTime:create(actionTime),cc.CallFunc:create(callback_fishing))
                                DoEventHandler._actionNode:runAction(action)
                                DoEventHandler.addGatherAction(action)
                            else--结束
                                DoEventHandler.gatherOver(event)
                            end
                        end

                        UIHandler:showGatherControl()
                        playGatherAction()

                        UIHandler:setGatherControlProgress(0, denominator)
                    end

                    prepareOk()
                else
                    DoEventHandler.gatherOver(event)
                end


            else
                DoEventHandler.gatherOver(event)
            end
        elseif todo == "chests" then
            local action = "pick"
            local actionOpen = "openbox"
            local actionOpen_Circle = "openbox_circle"
            if not cc.isDead(gatherNpc) then

                local function gatherNpcDisappear()

                    local function callback()
                        print("pick chests callback.")
                        if gatherNpc then
                            gatherNpc:stopMarkForEvent(false)
                            -- NpcManager:deleteNpcByUid(gatherNpc:getUid())
                            NpcManager:removePickPointByNpcId(gatherNpcId)
                        end
                        DoEventHandler.gatherOver(event)
                    end

                    gatherNpc = NpcManager:getNpcById(gatherNpcId)                        
                    if gatherNpc then
                        local sequenceAction = cc.Sequence:create(cc.FadeOut:create(0.3),cc.CallFunc:create(callback))
                        gatherNpc:runAction(sequenceAction)
                        gatherNpc:setChestsDisappear(true)
                    else
                        DoEventHandler.gatherOver(event)
                    end
                end

                local function getItemsRequest()

                    local function callback(msg)
                        if DoEventHandler.isEventStopGather() then return end
                        DoEventHandler.stopDelayAction()
                        
                        gatherNpcDisappear()
                    end
                    if isGatherNpcOver(gatherNpc) then
                        return
                    end
                    print("pb_pick.C2S_pick, gatherNpcId =",gatherNpcId)
                    app.session:request("pb_pick.C2S_Pick", { id = gatherNpcId }, callback, nil, function()
                        if DoEventHandler.isEventStopGather() then
                            return
                        end
                        DoEventHandler.stopDelayAction()

                        if isGatherNpcOver(gatherNpc) then
                            return
                        end
                        DoEventHandler.gatherOver(event)
                    end)
                    DoEventHandler.doDelayAction(5, function()
                        DoEventHandler.gatherOver(event)
                    end)
                end

                local function openBox()
                    local function prepareOk()
                        -- if DoEventHandler.isEventStopGather() then return end
                        -- DoEventHandler.stopDelayAction()
                        AM.playSoundById(2014)
                        local function openOver()
                            gatherNpc:playEventAction(actionOpen_Circle,nil,0,true)
                            getItemsRequest()
                        end
                        gatherNpc:playEventAction(actionOpen,openOver)
                    end
                    if isGatherNpcOver(gatherNpc) then return end

                    prepareOk()
                end

                local function playOpenAction(callback)
                    if gatherNpc and isCanGather(todo) and (not DoEventHandler.isStopGatherAction()) then
                        local duration = DoEventHandler.getCharacter():playEventsAction(action,nil,0,false)
                        local openTime = duration / 3--0.97
                        local openAction = cc.Sequence:create(cc.DelayTime:create(openTime),cc.CallFunc:create(callback))
                        DoEventHandler._actionNode:runAction(openAction)
                        DoEventHandler.addGatherAction(openAction)
                        gatherNpc:stopMarkForEvent(true)
                    else
                        DoEventHandler.gatherOver(event)
                    end
                end

                playOpenAction(openBox)
            else
                DoEventHandler.gatherOver(event)
            end

        end
    end
end

function DoEventHandler.playPuppetGatherActions(state,character)
    if not character then return end
    character:getOffRide()
    local function standBy(character)
        character:stopAllActions()
        if not character:isMove() then
            character:forceStandby()
        end
        FieldManager:fadeInAllCharacters(0.1)
    end

    local function playMiningAction(character)
        local action = "dig_loop"
        local actionTime = 1.2
        character:playEventsAction(action,nil,0,true,nil,actionTime)
    end

    local function playFishingAction(character)
        local function playGatherAction()
            local function fishOver()
                local function fishHookOver()
                    -- local actionNext = cc.Sequence:create(cc.CallFunc:create(playGatherAction))
                    -- DoEventHandler._actionNode:runAction(actionNext)
                    playGatherAction()
                end

                local actionTime = 1.7
                character:overEventActionPlaying()
                character:playEventsAction("fish_hook",nil,0,false,nil,actionTime)
                local action = cc.Sequence:create(cc.DelayTime:create(actionTime),cc.CallFunc:create(fishHookOver))
                character:runAction(action)
            end


            local function callback_fishing()
                local lowTime = tonumber(S("fishingtimelow"))
                local fishTime = lowTime / 1000.0

                local actionFishing = cc.Sequence:create(cc.DelayTime:create(fishTime),cc.CallFunc:create(fishOver))
                character:runAction(actionFishing)
                local fishLoopAction = "fish_wait"
                character:playEventsAction(fishLoopAction,nil,0,true)
            end

            local actionTime = 1.4
            local startAction = "fishing"
            character:playEventsAction(startAction,nil,0,false,nil,actionTime)
            local action = cc.Sequence:create(cc.DelayTime:create(actionTime),cc.CallFunc:create(callback_fishing))
            character:runAction(action)

        end

        playGatherAction()
    end

    local function playGatherGrassAction(character)
        local action = "pick"
        local actionTime = 2.92
        character:playEventsAction(action,nil,0,true,nil,actionTime)
    end

    local function playOpenChestAction(character)
        local action = "pick"
        local actionOpen = "openbox"
        local actionOpen_Circle = "openbox_circle"

        character:playEventsAction(action,nil,0,false)
    end

    if state == "none" then
        standBy(character)
    elseif state == "fishing" then
        playFishingAction(character)
    elseif state == "ore" then
        playMiningAction(character)
    elseif state == "grass" then
        playGatherGrassAction(character)
    elseif state == "chest" then
        playOpenChestAction(character)
    elseif state == "escort" then

    end
end

function DoEventHandler.doGatherUICallEvent(event)
    local ui = event.mUi
    local npcId = event.mNpcId

    local okEventsVec = event.mOkEventsVec
    local cancelEventsVec = event.mCancelEventsVec

    NpcManager:fadeOutExceptFocusNpc(npcId)

    local function ok()
        DoEventHandler.setCurrrentMark(nil)
        NpcManager:fadeInNpcs()
        DoEventHandler.startEvents(okEventsVec)
    end

    local function cancel()
        DoEventHandler.setCurrrentMark(nil)
        NpcManager:fadeInNpcs()
        DoEventHandler.startEvents(cancelEventsVec)
    end

    if ui == "ore" then
    elseif ui == "fishing" then
    elseif ui == "boss" then

    end
end

function DoEventHandler.doGatherControlEvent(event)
    --UIHandler:showGatherControl()

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doGatherToPointEvent(event)
    local npcId = event.mNpcId
    local npc = NpcManager:getNpcById(npcId)
    if npc then
        local ox = npc:getPositionX()
        local dx = 0
        local goffsetx = 50
        local character = DoEventHandler.getCharacter()
        if character then
            if character:getPositionX() <= ox then
                dx = ox - goffsetx
            else
                dx = ox + goffsetx
            end

            character:setEventTargetX(dx,nil,function()
                DoEventHandler.nextEventsVec(event)
                character:faceTo(ox)
            end)
        end
    else
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doSetStoneEvent(event)
end

function DoEventHandler.doGetOnRideEvent(event)
    DoEventHandler.getCharacter():getOnRide(UD:getMountTID())
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doGetOffRideEvent(event)
    FieldManager:onGetOffRide()
    TeamManager:autoTeamMemberGetOffRide()
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doGetRideEvent(event)
    local delayTime = event.mDelayTime
    local getOn = event.mGetOn
    local targetId = event.mTargetID

    local function getRide()
        if getOn then
            targetId = (targetId == nil) and UD:getMountTID() or targetId
            DoEventHandler.getCharacter():getOnRide(targetId)
        else
            FieldManager:onGetOffRide()
            TeamManager:autoTeamMemberGetOffRide()
        end
    end

    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(
                cc.DelayTime:create(delayTime),
                cc.CallFunc:create(getRide)))
    else
        getRide()
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doFaceToMainEvent(event)
    local npcId = event.mNpcId
    local npc = NpcManager:getNpcById(npcId)
    if npc then
        npc:faceToCharacter(DoEventHandler.getCharacter())
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doMainFaceToNpcEvent(event)
    local npcId = event.mNpcId

    local npc = NpcManager:getNpcById(npcId)
    if npc then
       DoEventHandler.getCharacter():faceTo(npc:getPositionX())
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doTaskLoopUIEvent(event)
    local npcId = event.mNpcId

    NpcManager:fadeOutExceptFocusNpc(npcId)
end

function DoEventHandler.doPrestigeDonateUIEvent(event)
end

function DoEventHandler.doPrestigeShopUIEvent(event)
    local npcId = event.mNpcId
    StoryManager:setEnterStoryMode(false)
    DoEventHandler.setOpenUI(true)
    NpcManager:fadeOutExceptFocusNpc(npcId)
    local returnEventsVec = event.mReturnEventsVec

    local function returnCallback()
        NpcManager:fadeInNpcs()
        DoEventHandler.startEvents(returnEventsVec)
    end
    app:sendMsg("PrestigeShopController", "openView", {returnCallback = returnCallback, npcId = npcId} )
end

function DoEventHandler.createBlackLayer()
    local InsetsRect = cc.rect(5,5,5,5)
    local blackLayer = ccui.Scale9Sprite:create(InsetsRect,Res.Public_Black_Img)
    blackLayer:setContentSize(cc.size(display.width,display.height))
    blackLayer:setAnchorPoint(cc.p(0,0))
    blackLayer:setPosition(cc.p(0,0))
    return blackLayer
end

function DoEventHandler.doBlackScreenEvent(event)
    local time = event.mTime
    local waitTime = event.mWaitTime
    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end
    UIHandler:getStoryModeUi():openTouchMask()

    DoEventHandler.mBlackScreenNode = DoEventHandler.createBlackLayer()
    DoEventHandler.mBlackScreenNode:setName("BlackScreenEvent")
    DoEventHandler.mBlackScreenNode:setOpacity(0)
    UIHandler:getStoryModeUi():addUI("mBlackScreenNode",DoEventHandler.mBlackScreenNode)

    local function callback()
        UIHandler:getStoryModeUi():removeUI("mBlackScreenNode",DoEventHandler.mBlackScreenNode)
        DoEventHandler.mBlackScreenNode = nil
        UIHandler:getStoryModeUi():closeTouchMask()
        DoEventHandler.nextEventsVec(event)
    end
    local action = cc.Sequence:create(cc.FadeIn:create(time),cc.DelayTime:create(waitTime),cc.FadeOut:create(time),cc.CallFunc:create(callback))
    DoEventHandler.mBlackScreenNode:runAction(action)
end

function DoEventHandler.doFadeScreenEvent(event)
    local time = event.mTime
    local fade = event.mFade
    local delayTime = event.mDelayTime

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end

    local function excute()
        local function callback()
            DoEventHandler.nextEventsVec(event)
        end

        if fade == "fadeIn" then
            UIHandler:blackScreenFade(fade,time)
        elseif fade == "fadeOut" then
            UIHandler:blackScreenFade(fade,time)
        end

        -- 执行回掉函数 和 fade动画 分开独立
        if time > 0 then
            DoEventHandler._actionNode:runAction( cc.Sequence:create(cc.DelayTime:create(time), cc.CallFunc:create(callback) ) )
        else
            callback()
        end
    end

    if delayTime > 0 then
        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(cc.DelayTime:create(delayTime),
            cc.CallFunc:create(function()
            excute()
        end)))
    else
        excute()
    end

end

function DoEventHandler.stopMapShakeAction()
    if DoEventHandler._mapShakeAction then
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():stopAction(DoEventHandler._mapShakeAction)
        end
        DoEventHandler._mapShakeAction = nil
    end
end

function DoEventHandler.doMapShakeEvent(event)
    local time = event.mTime
    local toNextTime = event.mToNextTime
    local shakeRange = event.mShakeRange
    local shakeDir = event.mShakeDir
    local delayTime = event.mDelayTime
    local x = event.mX
    local y = event.mY
    -- time = time + delayTime
    local shakeTime = 0.02

    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
        shakeTime = shakeTime / DoEventHandler.SKIP_FACTOR
    end
    local shakeAction
    local function toShake()
        shakeAction = cc.RepeatForever:create(
            cc.Sequence:create(
                cc.MoveTo:create(shakeTime,cc.p(math.random(0,x),math.random(0,y))),
                cc.DelayTime:create(0.05),
                cc.MoveTo:create(shakeTime,cc.p(math.random(0,x),0 - math.random(0,y))),
                cc.MoveTo:create(shakeTime,cc.p(0,0))
            )
        )
        if cc.isAlive(MapManager:getMap()) then
            MapManager:getMap():runAction(shakeAction)
        end
        DoEventHandler._mapShakeAction = shakeAction

        DoEventHandler._actionNode:runAction(
            cc.Sequence:create(cc.DelayTime:create(time),
                cc.CallFunc:create(function()
                    DoEventHandler.stopMapShakeAction()
                    if cc.isAlive(MapManager:getMap()) then
                        MapManager:getMap():setPosition(cc.p(0,0))
                    end
                    DoEventHandler.nextEventsVec(event)
            end)))

    end

    if delayTime > 0 then
        local shakeAction = cc.Sequence:create(cc.DelayTime:create(delayTime),cc.CallFunc:create(function()
            toShake()
        end))
        DoEventHandler._actionNode:runAction(shakeAction)
    else
        toShake()
    end
end

function DoEventHandler.setGoMapId(mapId)
    DoEventHandler._goMapId = mapId
end

function DoEventHandler.getGoMapId()
    return DoEventHandler._goMapId
end

function DoEventHandler.doCommonUIEvent(event)
    local npcId = event.mNpcId
    local ui = event.mUI
    StoryManager:setEnterStoryMode(false)
    DoEventHandler.setOpenUI(true)
    NpcManager:fadeOutExceptFocusNpc(npcId)
    local returnEventsVec = event.mReturnEventsVec
    local okEventsVec = event.mOkEventsVec

    DoEventHandler.setGoMapId(nil)

    local function returnCall()
        NpcManager:fadeInNpcs()
        DoEventHandler.startEvents(returnEventsVec)
    end

    local function okCall(mapId)
        if ui == "raid" then
            DoEventHandler.setGoMapId(mapId)
        end
        NpcManager:fadeInNpcs()
        DoEventHandler.startEvents(okEventsVec)
    end

    local function returnTheATreCallback()
        returnCall()
    end

    local function okTheatreCallback()
        returnCall()
    end

    local function returnExplorationCallback()
        returnCall()
    end

    local function returnCallback()
        returnCall()
    end

    local function exchangeShopReturnCallback()
        returnCall()
    end

    if ui == "compound" then--合成
        -- 打开合成界面，现已废弃
        returnCall()
    elseif ui == "recast" then--重铸
        -- 废弃
        returnCall()
    elseif ui == "identify" then--鉴定
    elseif ui == "theatre" then--剧场
    elseif ui == "exploration" then--挂机
    elseif ui == "guild" then--创建公会
        -- 废弃
        returnCall()
    elseif ui == "exchange" then
    elseif ui == "bigmap" then
        -- 大地图，已废弃
        returnCall()
    elseif ui == "merc" then
        UIHandler:handleMessage({id = Constant.FUNC_TYPE_MERCENARY,mode = "open",story = true,returnCallback = function()
            UIHandler:handleMessage({id = Constant.FUNC_TYPE_MERCENARY,mode = "close"})
            returnCall()
        end})
    elseif ui == "raid" then
        -- raid本，已废弃
        returnCall()
    elseif ui == "feast" then
        returnCall()
        -- 公会盛宴，已废弃
    elseif ui == "bountytask" then
        -- 循环赏金任务，已废弃
        returnCall()
    elseif ui == "interactive" then
        UIHandler:showInteractiveUi(npcId,returnCall)
    end

end

function DoEventHandler.doTypeWordsEvent(event)
    local wordsFlag = event.mWords
    local fontSize = event.mFontSize
    local typeTime = event.mTypeTime
    local lineLen = event.mLineLen
    local color = event.mColor
    local delayTime = event.mDelayTime
    local overDelay = event.mOverDelay
    if DoEventHandler.isSkipEvents() then
        typeTime = typeTime / DoEventHandler.SKIP_FACTOR
        delayTime = delayTime / DoEventHandler.SKIP_FACTOR
    end
    local typeWords = L(wordsFlag)

    local function typeOverCall()

        local action = cc.Sequence:create(cc.DelayTime:create(overDelay),cc.CallFunc:create(function()
            UIHandler:TypeWordsViewVisibility(false)
            DoEventHandler.nextEventsVec(event)
        end))

        DoEventHandler._actionNode:runAction(action)
    end

    UIHandler:TypeWordsViewVisibility(true,typeWords,fontSize,delayTime,typeTime,overDelay,lineLen,color,typeOverCall)
    --
end

function DoEventHandler.doFadeWordsEvent(event)
    local wordsFlag = event.mWords
    local fontSize = event.mFontSize
    local delayTime = event.mDelayTime
    local fadeTime = event.mFadeTime
    local lineWidth = event.mLineWidth
    local overDelayTime = event.mOverDelayTime
    local color = event.mColor
    local sy = event.mSy
    local nextTime = event.mNextTime
    local fadeWords = L(wordsFlag)
    local showType = event.mShowType

    -- 替换角色名字
    fadeWords = string.gsub(fadeWords, "<sign_name>", UD:getNickName())

    local function call()
        -- DoEventHandler.nextEventsVec(event)
    end
    local function call1()
        UIHandler:fadeWordsViewVisibility(false)

        -- 分成两个回调函数会有bug，当先调用call1时已经触发了释放，很可能调用不到call了
        DoEventHandler.nextEventsVec(event)
    end
    UIHandler:fadeWordsViewVisibility(true,{mode = "open",sy = sy,nextTime = nextTime,words = fadeWords,fontSize = fontSize,delayTime = delayTime,fadeTime = fadeTime,lineWidth = lineWidth,overDelayTime = overDelayTime,color = color,callback = call,callback1 = call1, showType = showType})
end

function DoEventHandler.doMapZoomEvent(event)
    local zoomValue = event.mZoomValue
    local time = event.mTime
    if DoEventHandler.isSkipEvents() then
        time = time / DoEventHandler.SKIP_FACTOR
    end
    local function callback()
        MapManager:pauseRunCameraZoomForEvent(false)
        DoEventHandler.nextEventsVec(event)
    end

    MapManager:pauseRunCameraZoomForEvent(true)
    MapManager:forceCameraZoomToDest({time = time,dstScale = zoomValue,call = callback})
end

function DoEventHandler.skipStoryViewVisibility(visible)
    if DoEventHandler.getController().mSkipStoryView then
        DoEventHandler.getController().mSkipStoryView:setVisible(visible)
    end
end

function DoEventHandler.removeSkipStoryView()
    if DoEventHandler.getController().mSkipStoryView then
        DoEventHandler.getController():removeChild(DoEventHandler.getController().mSkipStoryView)
        DoEventHandler.getController().mSkipStoryView = nil
    end
end

function DoEventHandler.removeSkipConfirm()
    if DoEventHandler.getController().mSkipStoryConfirmView then
        DoEventHandler.getController():removeChild(DoEventHandler.getController().mSkipStoryConfirmView)
        DoEventHandler.getController().mSkipStoryConfirmView = nil
    end
end

function DoEventHandler.doSkipOperateEvent(event)
    local show = event.mShow
    local taskId = event.mTaskId

    DoEventHandler.removeSkipConfirm()

    if show then
        local function okCall()
            -- DoEventHandler.setTaskMaskFlag(true)
            app.session:request("action.C2S_PlotWatch",{questId = taskId,result = 0,watchTime = DoEventHandler.getCostTime()})
            DoEventHandler.removeSkipConfirm()
            DoEventHandler.skipToEnd()
        end

        local function cancelCall()
            DoEventHandler.removeSkipConfirm()
            DoEventHandler.skipStoryViewVisibility(true)
        end

        local SkipStoryConfirm = require("app.secfunc.skipstory.SkipStoryConfirm")
        local blackMaskHeight = StoryManager:getStoryBlackMaskHeight()
        DoEventHandler.getController().mSkipStoryConfirmView = SkipStoryConfirm.new(blackMaskHeight)
        DoEventHandler.getController().mSkipStoryConfirmView:setOkCallback(okCall)
        DoEventHandler.getController().mSkipStoryConfirmView:setCancelCallback(cancelCall)
        DoEventHandler.getController():addChild(DoEventHandler.getController().mSkipStoryConfirmView,SceneZOrder.storyModeUIOperateZOrder)
        DoEventHandler.skipStoryViewVisibility(false)
    end

    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.removeCloud()
    if DoEventHandler.getController() and DoEventHandler.getController().mCloudNode then
        UIHandler:getStoryModeUi():removeUI("mCloudNode",DoEventHandler.getController().mCloudNode)
        DoEventHandler.getController().mCloudNode = nil
    end
end

function DoEventHandler.doCloudEvent(event)
    local directory = event.mDirectory
    local armName = event.mArmName
    local action = event.mAction
    local status = event.mStatus
    local loopTime = event.mLoopTime
    if DoEventHandler.isSkipEvents() then
        loopTime = loopTime / DoEventHandler.SKIP_FACTOR
    end

    DoEventHandler.removeCloud()

    local Armature = app:getClass("Armature")
    DoEventHandler.getController().mCloudNode = Armature.create({
        path = directory,
        armatureName = armName,
        animationName = "",
        skeletonName = armName,
        textureName = armName
    })
    DoEventHandler.getController().mCloudNode:setPosition(cc.p(display.width / 2,display.height / 2))

    UIHandler:getStoryModeUi():addUI("mCloudNode",DoEventHandler.getController().mCloudNode)

    local function cloudAppear()
        local function call()
            DoEventHandler.nextEventsVec(event)
        end
        local play = DoEventHandler.getController().mCloudNode:playAni({name = action,completeCallback = call})
    end

    local function cloudLoop()
        local play = DoEventHandler.getController().mCloudNode:playAni({name = action})

        local seqAction = cc.Sequence:create(cc.DelayTime:create(loopTime),cc.CallFunc:create(function()
            DoEventHandler.nextEventsVec(event)
        end))
        DoEventHandler.getController().mCloudNode:runAction(seqAction)
    end

    local function cloudDisappear()
        local function call()
            DoEventHandler.nextEventsVec(event)
        end
        local play = DoEventHandler.getController().mCloudNode:playAni({name = action,completeCallback = call})
    end

    if status == "appear" then
        cloudAppear()
    elseif status == "loop" then
        cloudLoop()
    elseif status == "disappear" then
        cloudDisappear()
    end
end

function DoEventHandler.doTransformEvent(event)
    local time = event.mTime
    local eType = event.mType

    DoEventHandler.removeCloud()

    local directory = "armatures/effect/cloud"
    local armName = "cloud"

    if eType == 1 then
        local Armature = app:getClass("Armature")
        DoEventHandler.getController().mCloudNode = Armature.create({
            path = directory,
            armatureName = armName,
            animationName = "",
            skeletonName = armName,
            textureName = armName
        })
        DoEventHandler.getController().mCloudNode:setPosition(cc.p(display.width / 2,display.height / 2))

        UIHandler:getStoryModeUi():addUI("mCloudNode",DoEventHandler.getController().mCloudNode)
        local action = "cloudcreate"
        DoEventHandler.getController().mCloudNode:playAni({name = action,completeCallback = function()
            action = "cloudloop"
            DoEventHandler.getController().mCloudNode:playAni({name = action})
            DoEventHandler.getController().mCloudNode:runAction(cc.Sequence:create(cc.DelayTime:create(time),cc.CallFunc:create(function()
                action = "clouddisappear"
                DoEventHandler.getController().mCloudNode:playAni({name = action,completeCallback = function()
                    DoEventHandler.nextEventsVec(event)

                end})
            end)))

        end})
    end
end

function DoEventHandler.doHearthStoneEvent(event)
    local playAction = event.mPlayAction
    if playAction then
        local function playLsAction()
            FieldManager:onPlayHearthStone()
        end
        local action = cc.Sequence:create(cc.DelayTime:create(0.2),cc.CallFunc:create(playLsAction))
        DoEventHandler._actionNode:runAction(action)
    end

    local function progressOver()
        UIHandler:handleMessage({id = Constant.FUNC_TYPE_TRANSFER,mode = "close"})
        DoEventHandler.nextEventsVec(event)
    end
    FieldManager:characterStopMove()
    FieldManager:onGetOffRide()
    UIHandler:handleMessage({id = Constant.FUNC_TYPE_TRANSFER,mode = "open",call = progressOver})
end

function DoEventHandler.doDisasterBattleEvent(event)
    local npcId = event.mNpcId

    local disasterNpc = NpcManager:getNpcIfUidNotNil(npcId)
    if disasterNpc then
        local function callback()
            DoEventHandler.DoTaskBattleEvent = true
            DoEventHandler.DoDisasterBattle = true
            DoEventHandler.CurTaskBattleEvent = event
            -- DoEventHandler.nextEventsVec(event)

            NpcManager:removePickPointByNpcId(npcId)
        end
        app.session:request("pb_pick.C2S_Pick",{id = npcId}, callback) -- TODO 还没测试
    else
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doSkipFlagStartEvent(event)
    local taskId = event.mTaskId
    local SkipOperateEvent = require("app.scripts.events.SkipOperateEvent")
    local skipOperateEvent = SkipOperateEvent.new({event = "SKIP_OPERATE_EVENT",show = true,taskId = taskId})
    DoEventHandler.doSkipOperateEvent(skipOperateEvent)
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doSkipFlagEndEvent(event)
    local SkipOperateEvent = require("app.scripts.events.SkipOperateEvent")
    local skipOperateEvent = SkipOperateEvent.new({event = "SKIP_OPERATE_EVENT",show = false})
    DoEventHandler.doSkipOperateEvent(skipOperateEvent)
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doSkipFlagEvent(event)
    local start = event.mStart
    local taskId = event.mTaskId
    if start then
        local SkipOperateEvent = require("app.scripts.events.SkipOperateEvent")
        local skipOperateEvent = SkipOperateEvent.new({event = "SKIP_OPERATE_EVENT",show = true,taskId = taskId})
        DoEventHandler.doSkipOperateEvent(skipOperateEvent)
    else
        local SkipOperateEvent = require("app.scripts.events.SkipOperateEvent")
        local skipOperateEvent = SkipOperateEvent.new({event = "SKIP_OPERATE_EVENT",show = false})
        DoEventHandler.doSkipOperateEvent(skipOperateEvent)
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doCameraBackToMaxEvent(event)
    local time = event.mTime
    local focusId = 0
    DoEventHandler.focusTrans(focusId,time)
    MapManager:forceCameraZoomToRunMax({resetPause = false,time = time,call = function()
        DoEventHandler.nextEventsVec(event)
    end})
end

function DoEventHandler.doDesktopVisibilityEvent(event)
    local visible = event.mVisible
    if visible then
        UIHandler:showDesktop()
    else
        UIHandler:hideDesktop()
    end
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doStoryBranchEvent(event)
    local okEventsVec = event.mOkEventsVec
    local cancelEventsVec = event.mCancelEventsVec

    local function ok()
        DoEventHandler.startEvents(okEventsVec)
        UIHandler:storyBranchVisibility(false)
    end

    local function cancel()
        DoEventHandler.startEvents(cancelEventsVec)
        UIHandler:storyBranchVisibility(false)
    end

    UIHandler:storyBranchVisibility(true,ok,cancel)
end

function DoEventHandler.doCreatePuppetEvent(event)
    local x = event.mX + DoEventHandler.Ox
    local delayTime = event.mDelayTime
    local dir = event.mDir
    local remove = event.mRemove
    local inBattle = event.mInBattle

    if remove then
        DoEventHandler.doDeletePuppetEvent()
    else
        if delayTime > 0 then
            DoEventHandler._actionNode:runAction(
                cc.Sequence:create(cc.DelayTime:create(delayTime),
                    cc.CallFunc:create(function()
                    FieldManager:buildPuppetCharacter(dir,x, inBattle)
            end)))
        else
            FieldManager:buildPuppetCharacter(dir,x, inBattle)
        end

        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doDeletePuppetEvent(event)
    FieldManager:deletePuppetCharacter()
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doWeatherControlEvent(event)
    local mode = event.mMode
    local weatherId = event.mWeatherId
    FieldManager:getWeatherSystem():playControl(mode,weatherId)
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doCheckTaskItemEvent(event)
end

function DoEventHandler.isPlayVideoEvent()
    return DoEventHandler.m_playVideoEvent
end

function DoEventHandler.doVideoPlayEvent(event)
    local path = event.mPath

    local fullPath = cc.FileUtils:getInstance():fullPathForFilename(path)
    local fileExist = cc.FileUtils:getInstance():isFileExist(fullPath)
    if fileExist then
        local platform = cc.Application:getInstance():getTargetPlatform()
        if platform ~= cc.PLATFORM_OS_ANDROID
            and platform ~= cc.PLATFORM_OS_IPHONE
            and platform ~= cc.PLATFORM_OS_IPAD then
            DoEventHandler.m_playVideoEvent = false
            DoEventHandler.nextEventsVec(event)
        else
            local layer = display.newLayer()
            local visibleRect = cc.Director:getInstance():getOpenGLView():getVisibleRect()
            local centerPos   = cc.p(visibleRect.x + visibleRect.width / 2,visibleRect.y + visibleRect.height / 2)
            local videoPlayer = ccexp.VideoPlayer:create()
            local function onVideoEventCallback(sener, eventType)
                if eventType == ccexp.VideoPlayerEvent.PLAYING then
                elseif eventType == ccexp.VideoPlayerEvent.PAUSED or
                 eventType == ccexp.VideoPlayerEvent.STOPPED or
                 eventType == ccexp.VideoPlayerEvent.COMPLETED then
                    local action = cc.Sequence:create(cc.DelayTime:create(0.2),cc.CallFunc:create(function()
                       --videoPlayer:stop()
                       UIHandler:removeVideo()
                       DoEventHandler.m_playVideoEvent = false
                       DoEventHandler.nextEventsVec(event)
                       AM.setAllMute(false)
                       MapManager:playMapMusic()
                    end))
                    DoEventHandler.getActionNode():runAction(action)
                end
            end
            local blackLayer = DoEventHandler.createBlackLayer()
            layer:addChild(blackLayer)

            videoPlayer:setKeepAspectRatioEnabled(true)
            videoPlayer:setFullScreenEnabled(true)
            videoPlayer:setPosition(centerPos)
            videoPlayer:setAnchorPoint(cc.p(0.5, 0.5))
            videoPlayer:setContentSize(cc.size(visibleRect.width,visibleRect.height))
            videoPlayer:addEventListener(onVideoEventCallback)
            layer:addChild(videoPlayer)

            videoPlayer:setFileName(fullPath)
            videoPlayer:play()

            MapManager:stopMapMusic()
            AM.stopAll()
            AM.setAllMute(true)

            DoEventHandler.m_playVideoEvent = true

            local screenSize = cc.Director:getInstance():getWinSize()
            layer:setPosition(cc.p(0,0))
            UIHandler:addVideo(layer)



            local function onTouchBegan(touch, event)
                videoPlayer:stop()
                return true
            end

            local function onTouchMoved(touch, event)
            end

            local function onTouchEnded(touch, event)
            end
            local function onTouchCanceled(touch, event)

            end

            local touchListener = cc.EventListenerTouchOneByOne:create()
            touchListener:setSwallowTouches(true)
            touchListener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN)
            touchListener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED)
            touchListener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED)
            touchListener:registerScriptHandler(onTouchCanceled,cc.Handler.EVENT_TOUCH_CANCELLED)
            cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(touchListener, layer)
        end
    else
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doMoveToNpcEvent(event)
    local npcId = event.mNpcId
    local speed = event.mSpeed
    local action = event.mAction
    local disx = event.mDisX
    local targetDir = event.mTargetDir

    local npc = NpcManager:getNpcById(npcId)
    if npc then
        local targetX = npc:getPositionX()
        local character = DoEventHandler.getCharacter()
        if targetDir == "l" then
            targetX = npc:getPositionX() - disx
        elseif targetDir == "r" then
            targetX = npc:getPositionX() + disx
        else
            if character:getPositionX() < npc:getPositionX() then
                targetX = npc:getPositionX() - disx
            else
                targetX = npc:getPositionX() + disx
            end
        end


        local function callback()
            MapManager:pauseRunCameraZoomForEvent(false)
            character:setRunAction(nil)
            DoEventHandler.nextEventsVec(event)
        end

        MapManager:pauseRunCameraZoomForEvent(true)

        character:setRunAction(action)
        character:setEventTargetX(targetX,speed,callback)
    else
        DoEventHandler.nextEventsVec(event)
    end
end

function DoEventHandler.doCountDownEvent(event)
    local keepTime = event.mKeepTime
    local hour = event.mHour
    local min = event.mMin
    local sec = event.mSec
    local r = event.mR
    local g = event.mG
    local b = event.mB
    local o = event.mO
    local fontSize = event.mFontSize
    local x = event.mX
    local y = event.mY
    local immediately = event.mImmediately

    if immediately then
        UIHandler:showCountDown({hour = hour,
            min = min,sec = sec,
            r = r,g = g,b = b,o = o,
            fontSize = fontSize,x = x,y = y})
        DoEventHandler.nextEventsVec(event)
    else
        local totalSec = hour * 60 * 60 + min * 60 + sec * 60

        if keepTime < totalSec then
            DoEventHandler._actionNode:runAction(cc.Sequence:create(cc.DelayTime:create(keepTime),cc.CallFunc:create(function()
                UIHandler:removeCountDown()
                DoEventHandler.nextEventsVec(event)
            end)))
        end

        UIHandler:showCountDown({hour = hour,
            min = min,sec = sec,
            r = r,g = g,b = b,o = o,
            fontSize = fontSize,x = x,y = y,callback = function()
            DoEventHandler.nextEventsVec(event)
        end})
    end


end

function DoEventHandler.doSceneMaskEvent(event)
    local r = event.mR
    local g = event.mG
    local b = event.mB
    local a = event.mA
    local enter = event.mEnter
    local fadeTime = event.mFadeTime
    if enter == 1 then
        local color = cc.c4b(r,g,b,a)
        MapManager:setMapMask(color,fadeTime)
    else
        MapManager:resetMapMask(fadeTime)
    end

    DoEventHandler.nextEventsVec(event)
end


function DoEventHandler.doSingleNpcMaskEvent(event)
    local npcId = event.mNpcId
    local r = event.mR
    local g = event.mG
    local b = event.mB
    local a = event.mA
    local fadeTime = event.mFadeTime
    local color = cc.c4b(r,g,b,a)
    NpcManager:setSingleNpcMask(npcId,color,fadeTime,function()
        DoEventHandler.nextEventsVec(event)
    end)
end

function DoEventHandler.doResetSceneMaskEvent(event)
    MapManager:resetMapMask()
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doEnterDungeonEvent(event)
    local mapId = event.mMapId
    local dungeonId = event.mDungeonId
    local dungeonSubId = event.mDungeonSubId
    local dungeonType = event.mType
    
    function quickEnter()
        DungeonManager:enterDungeonRequest(dungeonId,dungeonSubId,dungeonType,function()
            DoEventHandler.clearEventsStatus()
        end,function()
            DoEventHandler.nextEventsVec(event)
        end)
    end

    local dungeonInfo = GD:queryDungeonSubById(dungeonSubId)
    if dungeonInfo and dungeonInfo.mapType == 1 then -- 剧情副本
        if not app:getInst("TeamModel"):hasTeam() then
            quickEnter()
        else
            DoEventHandler.clearEventsStatus()
            NpcManager:reqEnterTaskDungeon(dungeonId, dungeonSubId)
        end
    else
        quickEnter()
    end
end

function DoEventHandler.doTransferStatusEvent(event)
    local start = event.mStart
    FieldManager:setTransferStart(start)
    DoEventHandler.nextEventsVec(event)
end

function DoEventHandler.doShowTvTestingEvent(event)
    local time = event.mTime
    
    local imageView = ccui.ImageView:create(Res.TvTestingBG)
    imageView:setAnchorPoint(cc.p(0, 0))
    imageView:ignoreContentAdaptWithSize(false)
    imageView:setContentSize(display.size)
    UIHandler:addPopDialog(imageView)

    local function call()
        imageView:removeFromParent()
        DoEventHandler.nextEventsVec(event)
    end

    if time > 0 then
        local seq = cc.Sequence:create(cc.DelayTime:create(time), cc.CallFunc:create( call ) )
        DoEventHandler._actionNode:runAction(seq)
    else
        call()
    end
end

function DoEventHandler.doTransferInSameMapEvent(event)
    local npcId = event.mNpcId
    if not npcId then
        DoEventHandler.nextEventsVec(event)
        return
    end
    MapManager:requestTpInSameMap(npcId)

    local seq = cc.Sequence:create(cc.DelayTime:create(0.3), cc.CallFunc:create(function()
        DoEventHandler.nextEventsVec(event)
    end))
    DoEventHandler._actionNode:runAction(seq)
end

return DoEventHandler
